BALL 1.5.0
Loading...
Searching...
No Matches
enumerator.h
Go to the documentation of this file.
1// -*- Mode: C++; tab-width: 2; -*-
2// vi: set ts=2:
3//
4
5#ifndef BALL_CONCEPT_ENUMERATOR_H
6#define BALL_CONCEPT_ENUMERATOR_H
7
8#ifndef BALL_COMMON_H
9# include <BALL/common.h>
10#endif
11
12#ifndef BALL_COMMON_EXCEPTION_H
14#endif
15
16#ifndef BALL_COMMON_RTTI_H
17# include <BALL/COMMON/rtti.h>
18#endif
19
20#ifndef BALL_CONCEPT_FORWARDITERATOR_H
22#endif
23
24#include <vector>
25#include <list>
26#include <algorithm>
27
28namespace BALL
29{
30
46 : private std::vector<Position>
47 {
48 public:
49
58 {
59 public:
60
61 IncompatibleIndex(const char* file, int line);
62 };
63
65
69
73
77 template <typename Variant, typename VariantIterator>
78 EnumeratorIndex(const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list);
79
83
85
91 const EnumeratorIndex& operator = (const EnumeratorIndex& rhs);
92
96 const EnumeratorIndex& operator = (Position index);
97
100 template <typename Variant, typename VariantIterator>
101 const EnumeratorIndex& operator = (const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list);
103
107
110 const std::vector<Size>& getModulus() const;
111
115
121 EnumeratorIndex& operator ++ ();
122
128 EnumeratorIndex& operator -- ();
129
132 Position operator [] (Position pos) const;
133
136 Position& operator [] (Position pos);
137
140 Size getSize() const;
141
153 EnumeratorIndex& operator << (Size modulus);
155
159
164 bool operator == (const EnumeratorIndex& rhs) const;
165
170 bool operator != (const EnumeratorIndex& rhs) const;
171
177 bool operator > (const EnumeratorIndex& rhs) const;
178
184 bool operator < (const EnumeratorIndex& rhs) const;
185
191 bool operator >= (const EnumeratorIndex& rhs) const;
192
198 bool operator <= (const EnumeratorIndex& rhs) const;
200
201 private:
203 std::vector<Size> modulus_;
205 std::vector<Size> base_multipliers_;
206 };
207
208
209 template <typename Variant, typename VariantIterator>
210 EnumeratorIndex::EnumeratorIndex(const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list)
211 : std::vector<Position>(variant_list.size()),
212 modulus_(variant_list.size()),
213 base_multipliers_(variant_list.size())
214 {
215 this->operator = (variant_list);
216 }
217
218
219 template <typename Variant, typename VariantIterator>
220 const EnumeratorIndex& EnumeratorIndex::operator =
221 (const std::list<std::pair<VariantIterator, std::vector<Variant> > >& variant_list)
222 {
223 resize(variant_list.size());
224 modulus_.resize(variant_list.size());
225 base_multipliers_.resize(variant_list.size());
226
227 // compute the base multipliers for later usage
228 Index i;
229 Size multiplier = 1;
230 typename std::list<std::pair<VariantIterator, std::vector<Variant> > >::const_iterator list_it = variant_list.begin();
231 for (i = (Size)(size() - 1); i >= 0; i--, list_it++)
232 {
233 operator[](i) = 0;
234 modulus_[i] = (Size)list_it->second.size();
235
236 base_multipliers_[i] = multiplier;
237 multiplier *= modulus_[i];
238 }
239
240 return *this;
241 }
242
243
272 template <class Container, class SiteIterator, class Variant>
274 {
275 protected:
276 class IteratorTraits_;
277
278 public:
279
283
292 typedef void (*MutatorFunction) (Variant&, const Variant&);
293
296 typedef std::vector<Variant> VariantVector;
297
300 typedef std::pair<SiteIterator, VariantVector> Site;
301
304 typedef std::list<Site> SiteList;
305
310
316
320
323 Enumerator();
324
330 Enumerator(Container& container);
331
336 Enumerator(Container& container, MutatorFunction mutator);
337
341 {
342 }
344
348
351 void addVariants(const SiteIterator& it, const VariantVector& variants)
352 {
353 variant_sites_.push_back(Site(it, variants));
355 }
356
359 void deleteVariants(const SiteIterator& it, const VariantVector& variants)
360 {
361 typename SiteList::iterator var_it;
362 var_it = std::find(variant_sites_.begin(), variant_sites_.end(), Site(it, variants));
363 if (var_it != variant_sites_.end())
364 {
365 variant_sites_.erase(var_it);
366 }
368 }
369
374 {
375 Size total = 1;
376 typename SiteList::iterator it;
377 for (it = variant_sites_.begin(); it != variant_sites_.end(); ++it)
378 {
379 total *= it->second.size();
380 }
381 return total;
382 }
383
387 Container& getCurrent();
388
393 void createCombination(const Position index);
394
400 void createCombination(const EnumeratorIndex& index);
402
406
408 Iterator begin();
409
411 Iterator end();
412
414 ConstIterator begin() const;
415
417 ConstIterator end() const;
419
420 protected:
421
422 friend class IteratorTraits_;
423
427 {
428 friend class Enumerator<Container, SiteIterator, Variant>;
429
430 public:
431
434
437
440
441 typedef EnumeratorIndex
443
444 typedef Container
446
448 : bound_(0),
449 position_(),
450 past_the_end_(false)
451 {
452 }
453
455 : bound_(const_cast<ContainerPointer>(&enumerator)),
456 position_(enumerator.variant_sites_),
457 past_the_end_(false)
458 {
459 }
460
462 {
463 return bound_;
464 }
465
467 {
468 return bound_;
469 }
470
471 bool isSingular() const
472 {
473 return (bound_ == 0);
474 }
475
477 {
478 return position_;
479 }
480
482 {
483 return position_;
484 }
485
486 bool operator == (const IteratorTraits_& traits) const
487 {
488 return ((bound_ == traits.bound_) && (position_ == traits.position_) && (past_the_end_ == traits.past_the_end_));
489 }
490
491 bool operator != (const IteratorTraits_& traits) const
492 {
493 return ((bound_ != traits.bound_) || (position_ != traits.position_) || (past_the_end_ != traits.past_the_end_));
494 }
495
496 bool isValid() const
497 {
498 return (bound_ != 0);
499 }
500
502 {
503 bound_ = 0;
504 position_ = 0;
505 past_the_end_ = false;
506 }
507
508 void toBegin()
509 {
510 position_ = 0;
511 past_the_end_ = false;
512 }
513
514 bool isBegin() const
515 {
516 return (position_ == EnumeratorIndex()) && (past_the_end_ == false);
517 }
518
519 void toEnd()
520 {
521 position_ = 0;
522 past_the_end_ = true;
523 }
524
525 bool isEnd() const
526 {
527 return past_the_end_;
528 }
529
531 {
532 validate();
533 return bound_->getCurrent();
534 }
535
536 const ValueType& getData() const
537 {
538 // This is logically const only!
540 return bound_->getCurrent();
541 }
542
543 void forward()
544 {
545 try
546 {
547 ++position_;
548 }
550 {
551 past_the_end_ = true;
552 position_ = 0;
553 }
554 }
555
556 void validate()
557 {
559 || (position_ != bound_->position_))
560 {
562 }
563 }
564
565 protected:
569 };
570
571 // the default mutation method (calling asignment operator)
572 static inline void defaultAssign_(Variant& a, const Variant& b)
573 {
574 a = b;
575 }
576
577 void mutate_(SiteIterator& it, const Variant& v)
578 {
579 mutator_(*it, v);
580 }
581
582 Container& container_;
587 };
588
589 template <typename Container, typename SiteIterator, typename Variant>
591 : container_(const_cast<Container&>(RTTI::getDefault<Container>())),
592 mutator_(0)
593 {
594 }
595
596 template <typename Container, typename SiteIterator, typename Variant>
598 : container_(container),
599 mutator_(defaultAssign_)
600 {
601 }
602
603 template <typename Container, typename SiteIterator, typename Variant>
606 (Container& container, typename Enumerator<Container, SiteIterator, Variant>::MutatorFunction mutator)
607 : container_(container),
608 mutator_(mutator)
609 {
610 }
611
612
613 template <typename Container, typename SiteIterator, typename Variant>
616 {
617 return container_;
618 }
619
620 template <typename Container, typename SiteIterator, typename Variant>
622 {
623 try
624 {
625 position_ = index;
626 createCombination(position_);
627 }
629 {
630 throw Exception::IndexOverflow(__FILE__, __LINE__, index);
631 }
632 }
633
634 template <typename Container, typename SiteIterator, typename Variant>
636 {
637 if (&index != &position_)
638 {
639 position_ = index;
640 }
641
642 typename SiteList::iterator it = variant_sites_.begin();
643 Position i((Position)(index.getSize() - 1));
644 for (; it != variant_sites_.end(); ++it, --i)
645 {
646 mutate_(it->first, it->second[index[i]]);
647 }
648
649 is_valid_position_ = true;
650 }
651
652 template <typename Container, typename SiteIterator, typename Variant>
658
659 template <typename Container, typename SiteIterator, typename Variant>
665
666 template <typename Container, typename VariantConstIterator, typename Variant>
672
673 template <typename Container, typename VariantConstIterator, typename Variant>
679
680
681# ifndef BALL_NO_INLINE_FUNCTIONS
682# include <BALL/CONCEPT/enumerator.iC>
683# endif
684
685}
686
687#endif // BALL_CONCEPT_ENUMERATOR_H
#define BALL_INLINE
Definition debug.h:15
STL namespace.
BALL_SIZE_TYPE Size
Size getModulus(Position pos) const
Size getSize() const
const EnumeratorIndex & operator=(const EnumeratorIndex &rhs)
const std::vector< Size > & getModulus() const
IncompatibleIndex(const char *file, int line)
ForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ > Iterator
Definition enumerator.h:309
Container & getCurrent()
Definition enumerator.h:615
std::pair< SiteIterator, VariantVector > Site
Definition enumerator.h:300
void mutate_(SiteIterator &it, const Variant &v)
Definition enumerator.h:577
Enumerator(Container &container, MutatorFunction mutator)
Container & container_
Definition enumerator.h:582
std::list< Site > SiteList
Definition enumerator.h:304
void(*) MutatorFunction(Variant &, const Variant &)
Definition enumerator.h:292
void createCombination(const Position index)
Definition enumerator.h:621
Iterator end()
Definition enumerator.h:661
ConstForwardIterator< Enumerator< Container, SiteIterator, Variant >, Container, EnumeratorIndex *, IteratorTraits_ > ConstIterator
Definition enumerator.h:314
MutatorFunction mutator_
Definition enumerator.h:583
void addVariants(const SiteIterator &it, const VariantVector &variants)
Definition enumerator.h:351
std::vector< Variant > VariantVector
Definition enumerator.h:296
void deleteVariants(const SiteIterator &it, const VariantVector &variants)
Definition enumerator.h:359
Iterator begin()
Definition enumerator.h:654
static void defaultAssign_(Variant &a, const Variant &b)
Definition enumerator.h:572
SiteList variant_sites_
Definition enumerator.h:584
EnumeratorIndex position_
Definition enumerator.h:585
const IteratorPosition & getPosition() const
Definition enumerator.h:481
IteratorTraits_(const ContainerType &enumerator)
Definition enumerator.h:454
ContainerPointer getContainer()
Definition enumerator.h:466
ContainerConstPointer getContainer() const
Definition enumerator.h:461
bool operator!=(const IteratorTraits_ &traits) const
Definition enumerator.h:491
const Enumerator< Container, SiteIterator, Variant > * ContainerConstPointer
Definition enumerator.h:439
Enumerator< Container, SiteIterator, Variant > ContainerType
Definition enumerator.h:433
IteratorPosition & getPosition()
Definition enumerator.h:476
Enumerator< Container, SiteIterator, Variant > * ContainerPointer
Definition enumerator.h:436
bool operator==(const IteratorTraits_ &traits) const
Definition enumerator.h:486
const ValueType & getData() const
Definition enumerator.h:536
#define BALL_EXPORT