Flow123d  DF_patch_fe_darcy_complete-579fe1e
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  /// Default constructor, reserved size is increased by one
48  {
49  data_.reserve(0);
50  }
51 
52  /// Constructor, create new instance with reserved size
53  RevertableList(std::size_t reserved_size, std::size_t enlarged_by = 0)
54  : temporary_size_(0), permanent_size_(0), enlarged_by_(enlarged_by)
55  {
56  data_.reserve(reserved_size);
57  }
58 
59  /// Copy constructor
62  {
63  data_.reserve( other.data_.capacity() );
64  }
65 
66  /// Assignment operator
67  inline RevertableList &operator=(const RevertableList &other) {
68  data_ = other.data_;
71  enlarged_by_ = other.enlarged_by_;
72  data_.reserve( other.data_.capacity() );
73 
74  return *this;
75  }
76  /**
77  * Reinit list initialized by default constructor.
78  *
79  * Set new reserved size and new enlarged by value.
80  * Important: Method can be called only before first usage of RevertableList!
81  */
82  void reinit_default_list(std::size_t new_reserved_size, std::size_t new_enlarged_by)
83  {
84  ASSERT_PERMANENT_EQ(reserved_size(), 0).error("Incorrect usage of method. Method must be called before first usage of RevertableList!");
85 
86  enlarged_by_ = new_enlarged_by;
87  data_.reserve(new_reserved_size);
88  }
89 
90  /**
91  * Resize to new reserved size.
92  *
93  * New size must be higher than actual size!
94  */
95  void resize(std::size_t new_size)
96  {
97  ASSERT_GE(new_size, reserved_size());
98  data_.reserve(new_size);
99  }
100 
101  /// Return permanent size of list.
102  inline std::size_t permanent_size() const
103  {
104  return permanent_size_;
105  }
106 
107  /// Return temporary size of list (full size of stored data).
108  inline std::size_t temporary_size() const
109  {
110  return temporary_size_;
111  }
112 
113  /// Return reserved (maximal) size.
114  inline std::size_t reserved_size() const
115  {
116  return data_.capacity();
117  }
118 
119  /**
120  * Add new item of list.
121  *
122  * New item is added to end of list and temporary size value is incremented.
123  * Method is equivalent with std::vector::push_back().
124  * This method needs to create copy of passed Type and it's beter to use emplace_back method.
125  */
126  inline std::size_t push_back(const Type &t)
127  {
128  if ( (temporary_size_ == reserved_size()) && (enlarged_by_ > 0) ) { // enlarge reserved size
129  this->resize( this->reserved_size() + enlarged_by_ );
130  }
131  data_.push_back(t);
132  temporary_size_++;
133  return temporary_size_;
134  }
135 
136  /**
137  * Create new item in list.
138  *
139  * New item is created at the end of list and temporary size value is incremented.
140  * Method is equivalent with std::vector::emplace_back().
141  * Method passes argumets of Type constructor.
142  */
143  template<class... Args>
144  inline std::size_t emplace_back(Args&&... args)
145  {
146  if ( (temporary_size_ == reserved_size()) && (enlarged_by_ > 0) ) { // enlarge reserved size
147  this->resize( this->reserved_size() + enlarged_by_ );
148  }
149  data_.emplace_back( std::forward<Args>(args)... );
150  temporary_size_++;
151  return temporary_size_;
152  }
153 
154  /// Finalize temporary part of data.
155  inline std::size_t make_permanent()
156  {
158  return temporary_size_;
159  }
160 
161  /// Erase temporary part of data.
162  inline std::size_t revert_temporary()
163  {
165  data_.resize(permanent_size_);
166  return temporary_size_;
167  }
168 
169  /// Clear the list.
170  inline void reset()
171  {
172  temporary_size_ = 0;
173  permanent_size_ = 0;
174  data_.resize(0);
175  }
176 
178  {
179  return data_.begin();
180  }
181 
183  {
184  return data_.begin() + permanent_size_;
185  }
186 
187  /// Return item on given position
188  const Type &operator[](std::size_t pos) const {
189  ASSERT_LT(pos, temporary_size_).error("Position is out of data size!\n");
190  return data_[pos];
191  }
192 
193 private:
194  std::vector<Type> data_; ///< Vector of items.
195  std::size_t temporary_size_; ///< Temporary size (full size of used data).
196  std::size_t permanent_size_; ///< Final size of data (part of finalize data).
197  std::size_t enlarged_by_; ///< Allow to enlarge list dynamically during call push_back if reserved size is full
198 };
199 
200 #endif /* REVARTABLE_LIST_HH_ */
Definitions of ASSERTS.
#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
#define ASSERT_PERMANENT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:329
Struct is a container that encapsulates variable size arrays.
std::size_t revert_temporary()
Erase temporary part of data.
std::vector< Type >::iterator begin()
RevertableList()
Default constructor, reserved size is increased by one.
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).
RevertableList & operator=(const RevertableList &other)
Assignment operator.
std::size_t emplace_back(Args &&... args)
void reinit_default_list(std::size_t new_reserved_size, std::size_t new_enlarged_by)
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.