Dune Core Modules (2.9.0)

arraylist.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 // SPDX-FileCopyrightInfo: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 
6 #ifndef DUNE_COMMON_ARRAYLIST_HH
7 #define DUNE_COMMON_ARRAYLIST_HH
8 
9 #include <array>
10 #include <cassert>
11 #include <memory>
12 #include <vector>
13 #include "iteratorfacades.hh"
14 
15 namespace Dune
16 {
17  // forward declaration
18  template<class T, int N, class A>
19  class ArrayListIterator;
20 
21  template<class T, int N, class A>
22  class ConstArrayListIterator;
23 
60  template<class T, int N=100, class A=std::allocator<T> >
61  class ArrayList
62  {
63  public:
69  typedef T MemberType;
70 
74  typedef T value_type;
75 
79  typedef T& reference;
80 
84  typedef const T& const_reference;
85 
89  typedef T* pointer;
90 
94  typedef const T* const_pointer;
95 
100  constexpr static int chunkSize_ = (N > 0) ? N : 1;
101 
106 
111 
115  typedef std::size_t size_type;
116 
120  typedef std::ptrdiff_t difference_type;
121 
127 
134 
140 
146 
151  inline void push_back(const_reference entry);
152 
159 
166 
171  inline size_type size() const;
172 
180  inline void purge();
181 
185  inline void clear();
190 
191  private:
192 
196  using SmartPointerAllocator = typename std::allocator_traits<A>::template rebind_alloc< std::shared_ptr< std::array<MemberType,chunkSize_> > >;
197 
201  using ArrayAllocator = typename std::allocator_traits<A>::template rebind_alloc< std::array<MemberType,chunkSize_> >;
202 
206  friend class ArrayListIterator<T,N,A>;
207  friend class ConstArrayListIterator<T,N,A>;
208 
210  std::vector<std::shared_ptr<std::array<MemberType,chunkSize_> >,
211  SmartPointerAllocator> chunks_;
220  size_type capacity_;
222  size_type size_;
224  size_type start_;
233  inline reference elementAt(size_type i);
234 
243  inline const_reference elementAt(size_type i) const;
244  };
245 
246 
250  template<class T, int N, class A>
251  class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N,A>,
252  typename A::value_type,
253  typename A::value_type &,
254  typename A::difference_type>
255  {
256 
257  friend class ArrayList<T,N,A>;
258  friend class ConstArrayListIterator<T,N,A>;
259  public:
263  typedef typename A::value_type MemberType;
264 
265  typedef typename A::difference_type difference_type;
266 
267  typedef typename A::size_type size_type;
268 
269  using reference = typename A::value_type &;
270 
271  using const_reference = typename A::value_type const&;
272 
278  constexpr static int chunkSize_ = (N > 0) ? N : 1;
279 
280 
286  inline bool equals(const ArrayListIterator<MemberType,N,A>& other) const;
287 
293  inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other) const;
294 
298  inline void increment();
299 
303  inline void decrement();
304 
309  inline reference elementAt(size_type i) const;
310 
315  inline reference dereference() const;
316 
328  inline void eraseToHere();
329 
331  inline size_type position(){return position_;}
332 
334  inline void advance(difference_type n);
335 
337  inline difference_type distanceTo(const ArrayListIterator<T,N,A>& other) const;
338 
340  inline ArrayListIterator() : position_(0), list_(nullptr)
341  {}
342 
343  private:
349  inline ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position);
350 
354  size_type position_;
358  ArrayList<T,N,A>* list_;
359  };
360 
364  template<class T, int N, class A>
366  : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N,A>,
367  const typename A::value_type,
368  typename A::value_type const&,
369  typename A::difference_type>
370  {
371 
372  friend class ArrayList<T,N,A>;
373  friend class ArrayListIterator<T,N,A>;
374 
375  public:
379  typedef typename A::value_type MemberType;
380 
381  typedef typename A::difference_type difference_type;
382 
383  typedef typename A::size_type size_type;
384 
385  using reference = typename A::value_type &;
386 
387  using const_reference = typename A::value_type const&;
388 
394  constexpr static int chunkSize_ = (N > 0) ? N : 1;
395 
401  inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other) const;
402 
406  inline void increment();
407 
411  inline void decrement();
412 
414  inline void advance(difference_type n);
415 
417  inline difference_type distanceTo(const ConstArrayListIterator<T,N,A>& other) const;
418 
423  inline const_reference elementAt(size_type i) const;
424 
429  inline const_reference dereference() const;
430 
431  inline ConstArrayListIterator() : position_(0), list_(nullptr)
432  {}
433 
435 
436  private:
437 
443  inline ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, size_type position);
444 
448  size_type position_;
452  const ArrayList<T,N,A>* list_;
453  };
454 
455 
456  template<class T, int N, class A>
458  : capacity_(0), size_(0), start_(0)
459  {
460  chunks_.reserve(100);
461  }
462 
463  template<class T, int N, class A>
465  capacity_=0;
466  size_=0;
467  start_=0;
468  chunks_.clear();
469  }
470 
471  template<class T, int N, class A>
472  size_t ArrayList<T,N,A>::size() const
473  {
474  return size_;
475  }
476 
477  template<class T, int N, class A>
479  {
480  size_t index=start_+size_;
481  if(index==capacity_)
482  {
483  chunks_.push_back(std::make_shared<std::array<MemberType,chunkSize_> >());
484  capacity_ += chunkSize_;
485  }
486  elementAt(index)=entry;
487  ++size_;
488  }
489 
490  template<class T, int N, class A>
492  {
493  return elementAt(start_+i);
494  }
495 
496 
497  template<class T, int N, class A>
499  {
500  return elementAt(start_+i);
501  }
502 
503  template<class T, int N, class A>
505  {
506  return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
507  }
508 
509 
510  template<class T, int N, class A>
512  {
513  return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
514  }
515 
516  template<class T, int N, class A>
518  {
519  return ArrayListIterator<T,N,A>(*this, start_);
520  }
521 
522  template<class T, int N, class A>
524  {
525  return ConstArrayListIterator<T,N,A>(*this, start_);
526  }
527 
528  template<class T, int N, class A>
530  {
531  return ArrayListIterator<T,N,A>(*this, start_+size_);
532  }
533 
534  template<class T, int N, class A>
536  {
537  return ConstArrayListIterator<T,N,A>(*this, start_+size_);
538  }
539 
540  template<class T, int N, class A>
542  {
543  // Distance to copy to the left.
544  size_t distance = start_/chunkSize_;
545  if(distance>0) {
546  // Number of chunks with entries in it;
547  size_t chunks = ((start_%chunkSize_ + size_)/chunkSize_ );
548 
549  // Copy chunks to the left.
550  std::copy(chunks_.begin()+distance,
551  chunks_.begin()+(distance+chunks), chunks_.begin());
552 
553  // Calculate new parameters
554  start_ = start_ % chunkSize_;
555  //capacity += distance * chunkSize_;
556  }
557  }
558 
559  template<class T, int N, class A>
560  void ArrayListIterator<T,N,A>::advance(difference_type i)
561  {
562  position_+=i;
563  }
564 
565  template<class T, int N, class A>
567  {
568  position_+=i;
569  }
570 
571 
572  template<class T, int N, class A>
574  {
575  // Makes only sense if we reference a common list
576  assert(list_==(other.list_));
577  return position_==other.position_ ;
578  }
579 
580 
581  template<class T, int N, class A>
583  {
584  // Makes only sense if we reference a common list
585  assert(list_==(other.list_));
586  return position_==other.position_ ;
587  }
588 
589 
590  template<class T, int N, class A>
592  {
593  // Makes only sense if we reference a common list
594  assert(list_==(other.list_));
595  return position_==other.position_ ;
596  }
597 
598  template<class T, int N, class A>
600  {
601  ++position_;
602  }
603 
604  template<class T, int N, class A>
606  {
607  ++position_;
608  }
609 
610  template<class T, int N, class A>
612  {
613  --position_;
614  }
615 
616  template<class T, int N, class A>
618  {
619  --position_;
620  }
621 
622  template<class T, int N, class A>
623  typename ArrayListIterator<T,N,A>::reference ArrayListIterator<T,N,A>::elementAt(size_type i) const
624  {
625  return list_->elementAt(i+position_);
626  }
627 
628  template<class T, int N, class A>
629  typename ConstArrayListIterator<T,N,A>::const_reference ConstArrayListIterator<T,N,A>::elementAt(size_type i) const
630  {
631  return list_->elementAt(i+position_);
632  }
633 
634  template<class T, int N, class A>
635  typename ArrayListIterator<T,N,A>::reference ArrayListIterator<T,N,A>::dereference() const
636  {
637  return list_->elementAt(position_);
638  }
639 
640  template<class T, int N, class A>
641  typename ConstArrayListIterator<T,N,A>::const_reference ConstArrayListIterator<T,N,A>::dereference() const
642  {
643  return list_->elementAt(position_);
644  }
645 
646  template<class T, int N, class A>
647  typename ArrayListIterator<T,N,A>::difference_type ArrayListIterator<T,N,A>::distanceTo(const ArrayListIterator<T,N,A>& other) const
648  {
649  // Makes only sense if we reference a common list
650  assert(list_==(other.list_));
651  return other.position_ - position_;
652  }
653 
654  template<class T, int N, class A>
655  typename ConstArrayListIterator<T,N,A>::difference_type ConstArrayListIterator<T,N,A>::distanceTo(const ConstArrayListIterator<T,N,A>& other) const
656  {
657  // Makes only sense if we reference a common list
658  assert(list_==(other.list_));
659  return other.position_ - position_;
660  }
661 
662  template<class T, int N, class A>
664  {
665  list_->size_ -= ++position_ - list_->start_;
666  // chunk number of the new position.
667  size_t posChunkStart = position_ / chunkSize_;
668  // number of chunks to deallocate
669  size_t chunks = (position_ - list_->start_ + list_->start_ % chunkSize_)
670  / chunkSize_;
671  list_->start_ = position_;
672 
673  // Deallocate memory not needed any more.
674  for(size_t chunk=0; chunk<chunks; chunk++) {
675  --posChunkStart;
676  list_->chunks_[posChunkStart].reset();
677  }
678 
679  // Capacity stays the same as the chunks before us
680  // are still there. They null pointers.
681  assert(list_->start_+list_->size_<=list_->capacity_);
682  }
683 
684  template<class T, int N, class A>
685  ArrayListIterator<T,N,A>::ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position)
686  : position_(position), list_(&arrayList)
687  {}
688 
689 
690  template<class T, int N, class A>
691  ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayList<T,N,A>& arrayList,
692  size_type position)
693  : position_(position), list_(&arrayList)
694  {}
695 
696  template<class T, int N, class A>
697  ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayListIterator<T,N,A>& other)
698  : position_(other.position_), list_(other.list_)
699  {}
700 
701 
703 }
704 #endif
A random access iterator for the Dune::ArrayList class.
Definition: arraylist.hh:255
constexpr static int chunkSize_
The number of elements in one chunk of the list.
Definition: arraylist.hh:278
size_type position()
Definition: arraylist.hh:331
A::value_type MemberType
The member type.
Definition: arraylist.hh:263
ArrayListIterator()
Standard constructor.
Definition: arraylist.hh:340
A dynamically growing random access list.
Definition: arraylist.hh:62
T value_type
Value type for stl compliance.
Definition: arraylist.hh:74
constexpr static int chunkSize_
The number of elements in one chunk of the list. This has to be at least one. The default is 100.
Definition: arraylist.hh:100
const T * const_pointer
The type of a const pointer to the type we store.
Definition: arraylist.hh:94
ArrayListIterator< MemberType, N, A > iterator
A random access iterator.
Definition: arraylist.hh:105
const T & const_reference
The type of a const reference to the type we store.
Definition: arraylist.hh:84
T & reference
The type of a reference to the type we store.
Definition: arraylist.hh:79
std::size_t size_type
The size type.
Definition: arraylist.hh:115
T MemberType
The member type that is stored.
Definition: arraylist.hh:69
T * pointer
The type of a pointer to the type we store.
Definition: arraylist.hh:89
ConstArrayListIterator< MemberType, N, A > const_iterator
A constant random access iterator.
Definition: arraylist.hh:110
std::ptrdiff_t difference_type
The difference type.
Definition: arraylist.hh:120
A constant random access iterator for the Dune::ArrayList class.
Definition: arraylist.hh:370
A::value_type MemberType
The member type.
Definition: arraylist.hh:379
constexpr static int chunkSize_
The number of elements in one chunk of the list.
Definition: arraylist.hh:394
A pair consisting of a global and local index.
Definition: indexset.hh:85
Base class for stl conformant forward iterators.
Definition: iteratorfacades.hh:434
reference operator[](size_type i)
Get the element at specific position.
Definition: arraylist.hh:491
iterator begin()
Get an iterator that is positioned at the first element.
Definition: arraylist.hh:517
bool equals(const ArrayListIterator< MemberType, N, A > &other) const
Comares two iterators.
Definition: arraylist.hh:573
void increment()
Increment the iterator.
Definition: arraylist.hh:599
size_type size() const
Get the number of elements in the list.
Definition: arraylist.hh:472
void purge()
Purge the list.
Definition: arraylist.hh:541
void decrement()
decrement the iterator.
Definition: arraylist.hh:611
void eraseToHere()
Erase all entries before the current position and the one at the current position.
Definition: arraylist.hh:663
ArrayList()
Constructs an Array list with one chunk.
Definition: arraylist.hh:457
const_iterator begin() const
Get a random access iterator that is positioned at the first element.
Definition: arraylist.hh:523
void increment()
Increment the iterator.
Definition: arraylist.hh:605
iterator end()
Get a random access iterator positioned after the last element.
Definition: arraylist.hh:529
const_reference elementAt(size_type i) const
Get the value of the list at an arbitrary position.
Definition: arraylist.hh:629
const_reference operator[](size_type i) const
Get the element at specific position.
Definition: arraylist.hh:498
void decrement()
decrement the iterator.
Definition: arraylist.hh:617
void advance(difference_type n)
Definition: arraylist.hh:566
const_iterator end() const
Get a random access iterator positioned after the last element.
Definition: arraylist.hh:535
const_reference dereference() const
Access the element at the current position.
Definition: arraylist.hh:641
void clear()
Delete all entries from the list.
Definition: arraylist.hh:464
reference elementAt(size_type i) const
Get the value of the list at an arbitrary position.
Definition: arraylist.hh:623
bool equals(const ConstArrayListIterator< MemberType, N, A > &other) const
Comares to iterators.
Definition: arraylist.hh:591
void advance(difference_type n)
Definition: arraylist.hh:560
difference_type distanceTo(const ConstArrayListIterator< T, N, A > &other) const
Definition: arraylist.hh:655
reference dereference() const
Access the element at the current position.
Definition: arraylist.hh:635
void push_back(const_reference entry)
Append an entry to the list.
Definition: arraylist.hh:478
difference_type distanceTo(const ArrayListIterator< T, N, A > &other) const
Definition: arraylist.hh:647
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:402
constexpr decltype(auto) elementAt(Container &&c, Index &&i)
Get element at given position from container.
Definition: hybridutilities.hh:135
constexpr HybridTreePath< T..., std::size_t > push_back(const HybridTreePath< T... > &tp, std::size_t i)
Appends a run time index to a HybridTreePath.
Definition: treepath.hh:281
This file implements iterator facade classes for writing stl conformant iterators.
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)