Flow123d  master-7cbe9e2
revertable_list.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file revertable_list.hh
15  * @brief
16  */
17 
18 #ifndef REVARTABLE_LIST_HH_
19 #define REVARTABLE_LIST_HH_
20 
21 
22 #include <new>
23 #include "system/asserts.hh"
24 
25 
26 /**
27  * @brief Struct is a container that encapsulates variable size arrays.
28  *
29  * Allows to:
30  * 1. Add new items to container (method push_back, items are stored as temporary.
31  * 2. Mark block of temporary items as final (use method make_permanent)
32  * or cancelled temporary item (method revert_temporary)
33  *
34  * This algorith allows to add blocks of data, evaluates external condition
35  * and possibly reverts unfinished block if condition is not met.
36  *
37  * Reserved (maximal) size is set in constructor. This size can be enlarged manually
38  * through method resize or constructor accepts parameter enlarged_by. If this value
39  * is greater than 0 size of container is automatically enlarged during call push_back
40  * if container is full.
41  */
42 template<class Type>
44 public:
45  /// Constructor, create new instance with reserved size
46  RevertableList(std::size_t reserved_size, std::size_t enlarged_by = 0)
47  : temporary_size_(0), permanent_size_(0), enlarged_by_(enlarged_by)
48  {
49  data_.reserve(reserved_size);
50  }
51 
52  /// Copy constructor
55  {
56  data_.reserve( other.data_.capacity() );
57  }
58 
59  /**
60  * Resize to new reserved size.
61  *
62  * New size must be higher than actual size!
63  */
64  void resize(std::size_t new_size)
65  {
66  ASSERT_GE(new_size, reserved_size());
67  data_.reserve(new_size);
68  }
69 
70  /// Return permanent size of list.
71  inline std::size_t permanent_size() const
72  {
73  return permanent_size_;
74  }
75 
76  /// Return temporary size of list (full size of stored data).
77  inline std::size_t temporary_size() const
78  {
79  return temporary_size_;
80  }
81 
82  /// Return reserved (maximal) size.
83  inline std::size_t reserved_size() const
84  {
85  return data_.capacity();
86  }
87 
88  /**
89  * Add new item of list.
90  *
91  * New item is added to end of list and temporary size value is incremented.
92  * Method is equivalent with std::vector::push_back().
93  * This method needs to create copy of passed Type and it's beter to use emplace_back method.
94  */
95  inline std::size_t push_back(const Type &t)
96  {
97  if (temporary_size_ == reserved_size()) { // enlarge reserved size
98  ASSERT_PERMANENT((enlarged_by_ > 0)).error("Revertable list overflow!\n");
99  this->resize( this->reserved_size() + enlarged_by_ );
100  }
101  data_.push_back(t);
102  temporary_size_++;
103  return temporary_size_;
104  }
105 
106  /**
107  * Create new item in list.
108  *
109  * New item is created at the end of list and temporary size value is incremented.
110  * Method is equivalent with std::vector::emplace_back().
111  * Method passes argumets of Type constructor.
112  */
113  template<class... Args>
114  inline std::size_t emplace_back(Args&&... args)
115  {
117  (enlarged_by_)(temporary_size_)(reserved_size()).error("Data array overflowed!\n");
118  if (temporary_size_ == reserved_size()) { // enlarge reserved size
119  this->resize( this->reserved_size() + enlarged_by_ );
120  }
121  data_.emplace_back( std::forward<Args>(args)... );
122  temporary_size_++;
123  return temporary_size_;
124  }
125 
126  /// Finalize temporary part of data.
127  inline std::size_t make_permanent()
128  {
130  return temporary_size_;
131  }
132 
133  /// Erase temporary part of data.
134  inline std::size_t revert_temporary()
135  {
137  data_.resize(permanent_size_);
138  return temporary_size_;
139  }
140 
141  /// Clear the list.
142  inline void reset()
143  {
144  temporary_size_ = 0;
145  permanent_size_ = 0;
146  data_.resize(0);
147  }
148 
150  {
151  return data_.begin();
152  }
153 
155  {
156  return data_.begin() + permanent_size_;
157  }
158 
159  /// Return item on given position
160  const Type &operator[](std::size_t pos) const {
161  ASSERT_LT(pos, temporary_size_).error("Position is out of data size!\n");
162  return data_[pos];
163  }
164 
165 private:
166  std::vector<Type> data_; ///< Vector of items.
167  std::size_t temporary_size_; ///< Temporary size (full size of used data).
168  std::size_t permanent_size_; ///< Final size of data (part of finalize data).
169  std::size_t enlarged_by_; ///< Allow to enlarge list dynamically during call push_back if reserved size is full
170 };
171 
172 #endif /* REVARTABLE_LIST_HH_ */
Definitions of ASSERTS.
#define ASSERT(expr)
Definition: asserts.hh:351
#define ASSERT_PERMANENT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
Definition: asserts.hh:348
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:301
#define ASSERT_GE(a, b)
Definition of comparative assert macro (Greater or Equal) only for debug mode.
Definition: asserts.hh:325
Struct is a container that encapsulates variable size arrays.
std::size_t revert_temporary()
Erase temporary part of data.
std::vector< Type >::iterator begin()
void resize(std::size_t new_size)
std::size_t reserved_size() const
Return reserved (maximal) size.
std::size_t enlarged_by_
Allow to enlarge list dynamically during call push_back if reserved size is full.
std::vector< Type >::iterator end()
std::size_t permanent_size_
Final size of data (part of finalize data).
std::size_t make_permanent()
Finalize temporary part of data.
std::vector< Type > data_
Vector of items.
std::size_t push_back(const Type &t)
RevertableList(const RevertableList &other)
Copy constructor.
void reset()
Clear the list.
const Type & operator[](std::size_t pos) const
Return item on given position.
std::size_t temporary_size_
Temporary size (full size of used data).
std::size_t emplace_back(Args &&... args)
std::size_t temporary_size() const
Return temporary size of list (full size of stored data).
RevertableList(std::size_t reserved_size, std::size_t enlarged_by=0)
Constructor, create new instance with reserved size.
std::size_t permanent_size() const
Return permanent size of list.