Loading...
Searching...
No Matches
enumerator.h
Go to the documentation of this file.
// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
#ifndef BALL_CONCEPT_ENUMERATOR_H
#define BALL_CONCEPT_ENUMERATOR_H
#ifndef BALL_COMMON_H
# include <BALL/common.h>
#endif
#ifndef BALL_COMMON_EXCEPTION_H
# include <BALL/COMMON/exception.h>
#endif
#ifndef BALL_COMMON_RTTI_H
# include <BALL/COMMON/rtti.h>
#endif
#ifndef BALL_CONCEPT_FORWARDITERATOR_H
# include <BALL/CONCEPT/forwardIterator.h>
#endif
#include <vector>
#include <list>
#include <algorithm>
namespace BALL
{
class BALL_EXPORT EnumeratorIndex
: private std::vector<Position>
{
public:
class BALL_EXPORT IncompatibleIndex
: public Exception::GeneralException
{
public:
IncompatibleIndex(const char* file, int line);
};
EnumeratorIndex();
template <typename Variant, typename VariantIterator>
EnumeratorIndex(const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list);
~EnumeratorIndex();
const EnumeratorIndex& operator = (const EnumeratorIndex& rhs);
const EnumeratorIndex& operator = (Position index);
template <typename Variant, typename VariantIterator>
const EnumeratorIndex& operator = (const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list);
const std::vector<Size>& getModulus() const;
Size getModulus(Position pos) const;
EnumeratorIndex& operator ++ ();
EnumeratorIndex& operator -- ();
Position operator [] (Position pos) const;
Position& operator [] (Position pos);
Size getSize() const;
EnumeratorIndex& operator << (Size modulus);
bool operator == (const EnumeratorIndex& rhs) const;
bool operator != (const EnumeratorIndex& rhs) const;
bool operator > (const EnumeratorIndex& rhs) const;
bool operator < (const EnumeratorIndex& rhs) const;
bool operator >= (const EnumeratorIndex& rhs) const;
bool operator <= (const EnumeratorIndex& rhs) const;
private:
std::vector<Size> modulus_;
std::vector<Size> base_multipliers_;
};
template <typename Variant, typename VariantIterator>
EnumeratorIndex::EnumeratorIndex(const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list)
: std::vector<Position>(variant_list.size()),
modulus_(variant_list.size()),
base_multipliers_(variant_list.size())
{
this->operator = (variant_list);
}
template <typename Variant, typename VariantIterator>
const EnumeratorIndex& EnumeratorIndex::operator =
(const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list)
{
resize(variant_list.size());
modulus_.resize(variant_list.size());
base_multipliers_.resize(variant_list.size());
// compute the base multipliers for later usage
Index i;
Size multiplier = 1;
typename std::list<std::pair<VariantIterator, std::vector<Variant> > >::const_iterator list_it = variant_list.begin();
for (i = (Size)(size() - 1); i >= 0; i--, list_it++)
{
operator[](i) = 0;
modulus_[i] = (Size)list_it->second.size();
base_multipliers_[i] = multiplier;
multiplier *= modulus_[i];
}
return *this;
}
template <class Container, class SiteIterator, class Variant>
class Enumerator
{
protected:
class IteratorTraits_;
public:
typedef void (*MutatorFunction) (Variant&, const Variant&);
typedef std::vector<Variant> VariantVector;
typedef std::pair<SiteIterator, VariantVector> Site;
typedef std::list<Site> SiteList;
typedef ForwardIterator<Enumerator<Container, SiteIterator, Variant>, Container, EnumeratorIndex*, IteratorTraits_>
Iterator;
typedef ConstForwardIterator<Enumerator<Container, SiteIterator, Variant>, Container, EnumeratorIndex*, IteratorTraits_>
ConstIterator;
Enumerator();
Enumerator(Container& container);
Enumerator(Container& container, MutatorFunction mutator);
~Enumerator()
{
}
void addVariants(const SiteIterator& it, const VariantVector& variants)
{
variant_sites_.push_back(Site(it, variants));
position_ = variant_sites_;
}
void deleteVariants(const SiteIterator& it, const VariantVector& variants)
{
typename SiteList::iterator var_it;
var_it = std::find(variant_sites_.begin(), variant_sites_.end(), Site(it, variants));
if (var_it != variant_sites_.end())
{
variant_sites_.erase(var_it);
}
position_ = variant_sites_;
}
Size countVariants()
{
Size total = 1;
typename SiteList::iterator it;
for (it = variant_sites_.begin(); it != variant_sites_.end(); ++it)
{
total *= it->second.size();
}
return total;
}
Container& getCurrent();
void createCombination(const Position index);
void createCombination(const EnumeratorIndex& index);
Iterator begin();
Iterator end();
ConstIterator begin() const;
ConstIterator end() const;
protected:
friend class IteratorTraits_;
class IteratorTraits_
{
friend class Enumerator<Container, SiteIterator, Variant>;
public:
typedef Enumerator<Container, SiteIterator, Variant>
ContainerType;
typedef Enumerator<Container, SiteIterator, Variant>*
ContainerPointer;
typedef const Enumerator<Container, SiteIterator, Variant>*
ContainerConstPointer;
typedef EnumeratorIndex
IteratorPosition;
typedef Container
ValueType;
IteratorTraits_()
: bound_(0),
position_(),
past_the_end_(false)
{
}
IteratorTraits_(const ContainerType& enumerator)
: bound_(const_cast<ContainerPointer>(&enumerator)),
position_(enumerator.variant_sites_),
past_the_end_(false)
{
}
ContainerConstPointer getContainer() const
{
return bound_;
}
ContainerPointer getContainer()
{
return bound_;
}
bool isSingular() const
{
return (bound_ == 0);
}
IteratorPosition& getPosition()
{
return position_;
}
const IteratorPosition& getPosition() const
{
return position_;
}
bool operator == (const IteratorTraits_& traits) const
{
return ((bound_ == traits.bound_) && (position_ == traits.position_) && (past_the_end_ == traits.past_the_end_));
}
bool operator != (const IteratorTraits_& traits) const
{
return ((bound_ != traits.bound_) || (position_ != traits.position_) || (past_the_end_ != traits.past_the_end_));
}
bool isValid() const
{
return (bound_ != 0);
}
void invalidate()
{
bound_ = 0;
position_ = 0;
past_the_end_ = false;
}
void toBegin()
{
position_ = 0;
past_the_end_ = false;
}
bool isBegin() const
{
return (position_ == EnumeratorIndex()) && (past_the_end_ == false);
}
void toEnd()
{
position_ = 0;
past_the_end_ = true;
}
bool isEnd() const
{
return past_the_end_;
}
ValueType& getData()
{
validate();
return bound_->getCurrent();
}
const ValueType& getData() const
{
// This is logically const only!
const_cast<typename Enumerator<Container, SiteIterator, Variant>::IteratorTraits_*>(this)->validate();
return bound_->getCurrent();
}
void forward()
{
try
{
++position_;
}
catch (Exception::IndexOverflow&)
{
past_the_end_ = true;
position_ = 0;
}
}
void validate()
{
if (!bound_->is_valid_position_
|| (position_ != bound_->position_))
{
bound_->createCombination(position_);
}
}
protected:
ContainerPointer bound_;
EnumeratorIndex position_;
bool past_the_end_;
};
// the default mutation method (calling asignment operator)
static inline void defaultAssign_(Variant& a, const Variant& b)
{
a = b;
}
void mutate_(SiteIterator& it, const Variant& v)
{
mutator_(*it, v);
}
Container& container_;
MutatorFunction mutator_;
SiteList variant_sites_;
EnumeratorIndex position_;
bool is_valid_position_;
};
template <typename Container, typename SiteIterator, typename Variant>
Enumerator<Container, SiteIterator, Variant>::Enumerator()
: container_(const_cast<Container&>(RTTI::getDefault<Container>())),
mutator_(0)
{
}
template <typename Container, typename SiteIterator, typename Variant>
Enumerator<Container, SiteIterator, Variant>::Enumerator(Container& container)
: container_(container),
mutator_(defaultAssign_)
{
}
template <typename Container, typename SiteIterator, typename Variant>
BALL_INLINE
Enumerator<Container, SiteIterator, Variant>::Enumerator
(Container& container, typename Enumerator<Container, SiteIterator, Variant>::MutatorFunction mutator)
: container_(container),
mutator_(mutator)
{
}
template <typename Container, typename SiteIterator, typename Variant>
BALL_INLINE
Container& Enumerator<Container, SiteIterator, Variant>::getCurrent()
{
return container_;
}
template <typename Container, typename SiteIterator, typename Variant>
void Enumerator<Container, SiteIterator, Variant>::createCombination(const Position index)
{
try
{
position_ = index;
createCombination(position_);
}
catch (EnumeratorIndex::IncompatibleIndex&)
{
throw Exception::IndexOverflow(__FILE__, __LINE__, index);
}
}
template <typename Container, typename SiteIterator, typename Variant>
void Enumerator<Container, SiteIterator, Variant>::createCombination(const EnumeratorIndex& index)
{
if (&index != &position_)
{
position_ = index;
}
typename SiteList::iterator it = variant_sites_.begin();
Position i((Position)(index.getSize() - 1));
for (; it != variant_sites_.end(); ++it, --i)
{
mutate_(it->first, it->second[index[i]]);
}
is_valid_position_ = true;
}
template <typename Container, typename SiteIterator, typename Variant>
BALL_INLINE
typename Enumerator<Container, SiteIterator, Variant>::Iterator Enumerator<Container, SiteIterator, Variant>::begin()
{
return Iterator::begin(*this);
}
template <typename Container, typename SiteIterator, typename Variant>
BALL_INLINE
typename Enumerator<Container, SiteIterator, Variant>::Iterator Enumerator<Container, SiteIterator, Variant>::end()
{
return Iterator::end(*this);
}
template <typename Container, typename VariantConstIterator, typename Variant>
BALL_INLINE
typename Enumerator<Container, VariantConstIterator, Variant>::ConstIterator Enumerator<Container, VariantConstIterator, Variant>::begin() const
{
return ConstIterator::begin(*this);
}
template <typename Container, typename VariantConstIterator, typename Variant>
BALL_INLINE
typename Enumerator<Container, VariantConstIterator, Variant>::ConstIterator Enumerator<Container, VariantConstIterator, Variant>::end() const
{
return ConstIterator::end(*this);
}
# ifndef BALL_NO_INLINE_FUNCTIONS
# include <BALL/CONCEPT/enumerator.iC>
# endif
}
#endif // BALL_CONCEPT_ENUMERATOR_H
exception.h
BALL_EXPORT
#define BALL_EXPORT
Definition COMMON/global.h:50
BALL::ConstForwardIterator
Definition forwardIterator.h:26
BALL::ConstForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ >::begin
static ConstForwardIterator begin(const Container &container)
BALL::ConstForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ >::end
static ConstForwardIterator end(const Container &container)
BALL::EnumeratorIndex::IncompatibleIndex
Definition enumerator.h:58
BALL::EnumeratorIndex::IncompatibleIndex::IncompatibleIndex
IncompatibleIndex(const char *file, int line)
BALL::EnumeratorIndex
Definition enumerator.h:47
BALL::EnumeratorIndex::~EnumeratorIndex
~EnumeratorIndex()
BALL::EnumeratorIndex::getModulus
Size getModulus(Position pos) const
BALL::EnumeratorIndex::EnumeratorIndex
EnumeratorIndex()
BALL::EnumeratorIndex::operator[]
Position operator[](Position pos) const
BALL::EnumeratorIndex::getSize
Size getSize() const
BALL::EnumeratorIndex::operator=
const EnumeratorIndex & operator=(const EnumeratorIndex &rhs)
BALL::EnumeratorIndex::getModulus
const std::vector< Size > & getModulus() const
BALL::Enumerator::IteratorTraits_
Definition enumerator.h:427
BALL::Enumerator::IteratorTraits_::getPosition
const IteratorPosition & getPosition() const
Definition enumerator.h:481
BALL::Enumerator::IteratorTraits_::IteratorTraits_
IteratorTraits_(const ContainerType &enumerator)
Definition enumerator.h:454
BALL::Enumerator::IteratorTraits_::getContainer
ContainerPointer getContainer()
Definition enumerator.h:466
BALL::Enumerator::IteratorTraits_::isValid
bool isValid() const
Definition enumerator.h:496
BALL::Enumerator::IteratorTraits_::isSingular
bool isSingular() const
Definition enumerator.h:471
BALL::Enumerator::IteratorTraits_::getData
ValueType & getData()
Definition enumerator.h:530
BALL::Enumerator::IteratorTraits_::getContainer
ContainerConstPointer getContainer() const
Definition enumerator.h:461
BALL::Enumerator::IteratorTraits_::operator!=
bool operator!=(const IteratorTraits_ &traits) const
Definition enumerator.h:491
BALL::Enumerator::IteratorTraits_::forward
void forward()
Definition enumerator.h:543
BALL::Enumerator::IteratorTraits_::isBegin
bool isBegin() const
Definition enumerator.h:514
BALL::Enumerator::IteratorTraits_::ContainerConstPointer
const Enumerator< Container, SiteIterator, Variant > * ContainerConstPointer
Definition enumerator.h:439
BALL::Enumerator::IteratorTraits_::ContainerType
Enumerator< Container, SiteIterator, Variant > ContainerType
Definition enumerator.h:433
BALL::Enumerator::IteratorTraits_::past_the_end_
bool past_the_end_
Definition enumerator.h:568
BALL::Enumerator::IteratorTraits_::invalidate
void invalidate()
Definition enumerator.h:501
BALL::Enumerator::IteratorTraits_::getPosition
IteratorPosition & getPosition()
Definition enumerator.h:476
BALL::Enumerator::IteratorTraits_::toBegin
void toBegin()
Definition enumerator.h:508
BALL::Enumerator::IteratorTraits_::validate
void validate()
Definition enumerator.h:556
BALL::Enumerator::IteratorTraits_::ContainerPointer
Enumerator< Container, SiteIterator, Variant > * ContainerPointer
Definition enumerator.h:436
BALL::Enumerator::IteratorTraits_::operator==
bool operator==(const IteratorTraits_ &traits) const
Definition enumerator.h:486
BALL::Enumerator::IteratorTraits_::IteratorTraits_
IteratorTraits_()
Definition enumerator.h:447
BALL::Enumerator::IteratorTraits_::isEnd
bool isEnd() const
Definition enumerator.h:525
BALL::Enumerator::IteratorTraits_::toEnd
void toEnd()
Definition enumerator.h:519
BALL::Enumerator::IteratorTraits_::bound_
ContainerPointer bound_
Definition enumerator.h:566
BALL::Enumerator::IteratorTraits_::ValueType
Container ValueType
Definition enumerator.h:445
BALL::Enumerator::IteratorTraits_::position_
EnumeratorIndex position_
Definition enumerator.h:567
BALL::Enumerator::IteratorTraits_::IteratorPosition
EnumeratorIndex IteratorPosition
Definition enumerator.h:442
BALL::Enumerator::IteratorTraits_::getData
const ValueType & getData() const
Definition enumerator.h:536
BALL::Enumerator::countVariants
Size countVariants()
Definition enumerator.h:373
BALL::Enumerator::Enumerator
Enumerator()
Definition enumerator.h:590
BALL::Enumerator::Iterator
ForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ > Iterator
Definition enumerator.h:309
BALL::Enumerator::VariantVector
std::vector< Variant > VariantVector
Definition enumerator.h:296
BALL::Enumerator::createCombination
void createCombination(const EnumeratorIndex &index)
Definition enumerator.h:635
BALL::Enumerator::getCurrent
Container & getCurrent()
Definition enumerator.h:615
BALL::Enumerator::Site
std::pair< SiteIterator, VariantVector > Site
Definition enumerator.h:300
BALL::Enumerator::is_valid_position_
bool is_valid_position_
Definition enumerator.h:586
BALL::Enumerator::mutate_
void mutate_(SiteIterator &it, const Variant &v)
Definition enumerator.h:577
BALL::Enumerator::Enumerator
Enumerator(Container &container, MutatorFunction mutator)
BALL::Enumerator::ConstIterator
ConstForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ > ConstIterator
Definition enumerator.h:314
BALL::Enumerator< Container, SiteIterator, Variant > *::container_
Container & container_
Definition enumerator.h:582
BALL::Enumerator::SiteList
std::list< Site > SiteList
Definition enumerator.h:304
BALL::Enumerator::createCombination
void createCombination(const Position index)
Definition enumerator.h:621
BALL::Enumerator::end
Iterator end()
Definition enumerator.h:661
BALL::Enumerator< Container, SiteIterator, Variant > *::IteratorTraits_
friend class IteratorTraits_
Definition enumerator.h:422
BALL::Enumerator::mutator_
MutatorFunction mutator_
Definition enumerator.h:583
BALL::Enumerator::addVariants
void addVariants(const SiteIterator &it, const VariantVector &variants)
Definition enumerator.h:351
BALL::Enumerator::Enumerator
Enumerator(Container &container)
Definition enumerator.h:597
BALL::Enumerator::begin
ConstIterator begin() const
Definition enumerator.h:668
BALL::Enumerator::deleteVariants
void deleteVariants(const SiteIterator &it, const VariantVector &variants)
Definition enumerator.h:359
BALL::Enumerator::~Enumerator
~Enumerator()
Definition enumerator.h:340
BALL::Enumerator::begin
Iterator begin()
Definition enumerator.h:654
BALL::Enumerator::defaultAssign_
static void defaultAssign_(Variant &a, const Variant &b)
Definition enumerator.h:572
BALL::Enumerator::end
ConstIterator end() const
Definition enumerator.h:675
BALL::Enumerator::MutatorFunction
void(* MutatorFunction)(Variant &, const Variant &)
Definition enumerator.h:292
BALL::Enumerator< Container, SiteIterator, Variant > *::variant_sites_
SiteList variant_sites_
Definition enumerator.h:584
BALL::Enumerator< Container, SiteIterator, Variant > *::position_
EnumeratorIndex position_
Definition enumerator.h:585
BALL::Exception::GeneralException
Definition COMMON/exception.h:61
BALL::Exception::IndexOverflow
Definition COMMON/exception.h:164
BALL::ForwardIterator
Definition forwardIterator.h:199
BALL::ForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ >::begin
static ForwardIterator begin(const Container &container)
BALL::ForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ >::end
static ForwardIterator end(const Container &container)
common.h
BALL_INLINE
#define BALL_INLINE
Definition debug.h:15
forwardIterator.h
BALL::RTTI
Definition rtti.h:67
BALL
Definition constants.h:13
BALL::Size
BALL_SIZE_TYPE Size
Definition COMMON/global.h:114
BALL::Position
BALL_SIZE_TYPE Position
Definition COMMON/global.h:140
BALL::Index
BALL_INDEX_TYPE Index
Definition COMMON/global.h:105
std
STL namespace.
rtti.h