Line data Source code
1 : /*
2 : * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UG__pointer_array_impl__
34 : #define __H__UG__pointer_array_impl__
35 :
36 : #include <cstring>
37 : #include <algorithm>
38 :
39 : namespace ug
40 : {
41 :
42 : template <class TPtr>
43 0 : PointerConstArray<TPtr>::
44 : PointerConstArray() :
45 0 : m_array(NULL), m_data(NULL), m_size(0), m_capacity(0)
46 : {
47 0 : }
48 :
49 : template <class TPtr>
50 : PointerConstArray<TPtr>::
51 : PointerConstArray(const PointerConstArray& pa)
52 : {
53 : assign_pointer_const_array(pa);
54 : }
55 :
56 : template <class TPtr>
57 : PointerConstArray<TPtr>::
58 : ~PointerConstArray()
59 : {
60 : // only free local memory...
61 0 : if(m_data)
62 0 : delete[] m_data;
63 0 : }
64 :
65 : template <class TPtr>
66 : PointerConstArray<TPtr>& PointerConstArray<TPtr>::
67 : operator=(const PointerConstArray& pa)
68 : {
69 : // free memory if necessary
70 : if(m_data)
71 : delete[] m_data;
72 :
73 : // assign the new class
74 : assign_pointer_const_array(pa);
75 :
76 : // return reference to this
77 : return *this;
78 : }
79 :
80 : template <class TPtr>
81 : void PointerConstArray<TPtr>::
82 : assign_pointer_const_array(const PointerConstArray& pa)
83 : {
84 : m_size = pa.m_size;
85 : // check whether pa points to an external array or not
86 : if(pa.m_array != pa.m_data){
87 : // we'll point to the same external array
88 : m_array = pa.m_array;
89 : m_data = NULL;
90 : m_capacity = 0;
91 : }
92 : else{
93 : // we'll create our own array and copy the contents
94 : if(m_size){
95 : m_data = new TPtr[m_size];
96 : memcpy(m_data, pa.m_data, sizeof(TPtr) * m_size);
97 : }else
98 : m_data = NULL;
99 : m_capacity = m_size;
100 : m_array = m_data;
101 : }
102 : }
103 :
104 : template <class TPtr>
105 : inline size_t PointerConstArray<TPtr>::
106 : size() const
107 : {
108 0 : return m_size;
109 : }
110 :
111 : template <class TPtr>
112 : inline bool PointerConstArray<TPtr>::
113 : empty() const
114 : {
115 : return m_size == 0;
116 : }
117 :
118 : template <class TPtr>
119 : inline TPtr const PointerConstArray<TPtr>::
120 : operator[](size_t i) const
121 : {
122 : UG_ASSERT(i < m_size, "bad index!");
123 0 : return m_array[i];
124 : }
125 :
126 : template <class TPtr>
127 0 : void PointerConstArray<TPtr>::
128 : set_external_array(TPtr const *array, size_t size, bool bCopy)
129 : {
130 0 : if(bCopy){
131 : //don't call resize!
132 0 : if(size > m_capacity){
133 0 : delete[] m_data;
134 0 : m_data = new TPtr[size];
135 0 : m_capacity = size;
136 : }
137 :
138 0 : if(size > 0)
139 0 : memcpy(m_data, array, sizeof(TPtr) * size);
140 :
141 0 : m_array = m_data;
142 0 : m_size = size;
143 : }
144 : else{
145 0 : m_array = array;
146 0 : m_size = size;
147 : }
148 0 : }
149 :
150 : template <class TPtr>
151 : void PointerConstArray<TPtr>::
152 : reserve(size_t capacity)
153 : {
154 : // only copy old data, if we're actually using it
155 : reserve(capacity, m_array == m_data);
156 : }
157 :
158 : template <class TPtr>
159 0 : void PointerConstArray<TPtr>::
160 : reserve(size_t capacity, bool copyOldData)
161 : {
162 0 : if(capacity > m_capacity){
163 0 : PtrArray newData = new TPtr[capacity];
164 :
165 0 : if(m_data && copyOldData)
166 0 : memcpy(newData, m_data, sizeof(TPtr) * m_capacity);
167 :
168 0 : m_capacity = capacity;
169 :
170 : // update pointers to new memory location and free old data.
171 : // if m_array still points to an external array, we won't update the pointer.
172 0 : if(m_array == m_data)
173 0 : m_array = newData;
174 :
175 0 : delete[] m_data;
176 0 : m_data = newData;
177 : }
178 0 : }
179 :
180 : template <class TPtr>
181 : void PointerConstArray<TPtr>::
182 : clear()
183 : {
184 0 : m_size = 0;
185 0 : }
186 :
187 : template <class TPtr>
188 0 : void PointerConstArray<TPtr>::
189 : push_back(TPtr p)
190 : {
191 : using namespace std;
192 : // first make sure, that m_array is contained in m_data
193 0 : if(m_array != m_data){
194 : // since we push something back, we double the capacity now
195 0 : reserve(max<size_t>(1, m_size * 2), false);
196 0 : if(m_size > 0)
197 0 : memcpy(m_data, m_array, sizeof(TPtr) * m_size);
198 0 : m_array = m_data;
199 : }
200 :
201 : // now check whether there's space left in m_data
202 0 : if(m_size >= m_capacity)
203 0 : reserve(max<size_t>(1, m_capacity * 2), true);
204 :
205 : // assign the new entry
206 0 : m_data[m_size] = p;
207 0 : ++m_size;
208 0 : }
209 :
210 : }// end of namespace
211 :
212 : #endif
|