36 #ifndef BGEOT_SMALL_VECTOR_H
37 #define BGEOT_SMALL_VECTOR_H
41 #ifdef DEBUG_SMALL_VECTOR
43 # define SVEC_ASSERT(x) assert(x)
45 # define SVEC_ASSERT(x)
50 class APIDECL block_allocator {
52 typedef gmm::uint16_type uint16_type;
53 typedef gmm::uint32_type node_id;
56 enum { p2_BLOCKSZ = 8, BLOCKSZ = 1<<p2_BLOCKSZ };
57 enum { OBJ_SIZE_LIMIT = 129 };
58 enum { MAXREF = 256 };
65 uint16_type first_unused_chunk, count_unused_chunk;
79 data =
static_cast<unsigned char*
>(::operator
new(BLOCKSZ*objsz + BLOCKSZ));
81 memset(data, 0, BLOCKSZ);
86 if (data) { ::operator
delete(data); };
87 data = 0; first_unused_chunk = 0; count_unused_chunk = BLOCKSZ;
89 unsigned char& refcnt(
size_type pos) {
return data[pos]; }
90 bool empty()
const {
return data == 0; }
95 std::vector<block> blocks;
102 void * obj_data(node_id
id) {
103 return blocks[
id/BLOCKSZ].data + BLOCKSZ + (
id%BLOCKSZ)*blocks[
id/BLOCKSZ].objsz;
105 dim_type obj_sz(node_id
id) {
106 return dim_type(blocks[
id/BLOCKSZ].objsz);
109 unsigned char& refcnt(node_id
id) {
110 return blocks[
id/BLOCKSZ].refcnt(
id%BLOCKSZ);
112 node_id inc_ref(node_id
id) {
113 if (
id && ++refcnt(
id) == 0) {
119 void dec_ref(node_id
id) {
120 SVEC_ASSERT(
id==0 || refcnt(
id));
121 if (
id && --refcnt(
id) == 0) {
126 void duplicate_if_aliased(node_id&
id) {
127 if (refcnt(
id) != 1) {
129 id = duplicate(
id); SVEC_ASSERT(
id == 0 || refcnt(
id)==1);
135 void deallocate(node_id nid);
139 node_id duplicate(node_id
id) {
140 node_id id2 = allocate(obj_sz(
id));
141 memcpy(obj_data(id2),obj_data(
id),obj_sz(
id));
149 class APIDECL static_block_allocator {
152 static block_allocator *palloc;
154 static_block_allocator();
156 block_allocator& allocator()
const;
157 bool allocator_destroyed()
const;
161 #ifdef GETFEM_HAS_OPENMP
164 template<
typename T>
class small_vector :
public std::vector<T>
167 using typename std::vector<T>::const_iterator;
168 using typename std::vector<T>::iterator;
169 const_iterator begin()
const {
return std::vector<T>::begin(); }
170 iterator begin() {
return std::vector<T>::begin(); }
171 const_iterator end()
const {
return std::vector<T>::end(); }
172 iterator end() {
return std::vector<T>::end(); }
174 const_iterator const_begin()
const {
return std::vector<T>::cbegin(); }
175 const_iterator const_end()
const {
return std::vector<T>::cend(); }
176 dim_type size()
const {
return dim_type(std::vector<T>::size()); }
178 const small_vector<T>& operator=(
const small_vector<T>& other) {
179 std::vector<T>::operator=(other);
183 small_vector() : std::vector<T>() {}
185 explicit small_vector(
size_type n) : std::vector<T>(n) {}
187 small_vector(
const small_vector<T>& v) : std::vector<T>(v) {}
189 small_vector(
const std::vector<T>& v) : std::vector<T>(v) {}
191 small_vector(T v1, T v2) : std::vector<T>(2)
192 { (*this)[0] = v1; (*this)[1] = v2; }
194 small_vector(T v1, T v2, T v3) : std::vector<T>(3)
195 { (*this)[0] = v1; (*this)[1] = v2; (*this)[2] = v3; }
197 template<
class UNOP> small_vector(
const small_vector<T>& a, UNOP op)
198 : std::vector<T>(a.size())
199 { std::transform(a.begin(), a.end(), begin(), op); }
201 template<
class BINOP> small_vector(
const small_vector<T>& a,
const small_vector<T>& b, BINOP op)
202 : std::vector<T>(a.size())
203 { std::transform(a.begin(), a.end(), b.begin(), begin(), op); }
209 template<
typename T>
class small_vector :
public static_block_allocator {
210 typedef block_allocator::node_id node_id;
215 typedef T value_type;
217 typedef const T * const_pointer;
218 typedef T& reference;
219 typedef const T & const_reference;
221 typedef const T * const_iterator;
224 GMM_ASSERT2(l <= size(),
"out of range, ind=" << l <<
" size=" << size());
227 value_type operator[](
size_type l)
const {
228 GMM_ASSERT2(l <= size(),
"out of range, ind=" << l <<
" size=" << size());
229 return const_base()[l];
231 value_type at(
size_type l)
const {
return const_base()[l]; }
232 iterator begin() {
return base(); }
233 const_iterator begin()
const {
return const_base(); }
234 const_iterator const_begin()
const {
return const_base(); }
235 iterator end() {
return base()+size(); }
236 const_iterator end()
const {
return const_base()+size(); }
237 const_iterator const_end()
const {
return const_base()+size(); }
239 if (n == size())
return;
242 memcpy(other.base(), const_base(), std::min(size(),other.size())*
sizeof(value_type));
243 SVEC_ASSERT(
id==0 || refcnt());
245 SVEC_ASSERT(refcnt()); SVEC_ASSERT(other.id == 0 || other.refcnt());
246 }
else { allocator().dec_ref(
id);
id=0; }
250 node_id id2 = allocator().inc_ref(other.id);
251 allocator().dec_ref(
id);
id = id2;
252 SVEC_ASSERT(
id == 0 || refcnt()); SVEC_ASSERT(other.id == 0 || other.refcnt());
259 explicit small_vector(
const std::vector<T>& v) : id(allocate(v.size())) {
260 std::copy(v.begin(),v.end(),begin());
267 if (!allocator_destroyed())
268 allocator().dec_ref(
id);
272 { begin()[0] = v1; begin()[1] = v2; }
274 { begin()[0] = v1; begin()[1] = v2; begin()[2] = v3; }
276 : id(allocate(a.size())) { std::transform(a.begin(), a.end(), begin(), op); }
278 : id(allocate(a.size())) { std::transform(a.begin(), a.end(), b.begin(), begin(), op); }
279 bool empty()
const {
return id==0; }
280 unsigned char refcnt()
const {
return allocator().refcnt(
id); }
281 dim_type size()
const
282 {
return dim_type(allocator().obj_sz(
id)/
sizeof(value_type)); }
292 {
return -1.*(*this); }
299 const_iterator b = other.begin(); iterator it = begin();
300 for (
size_type i=0; i < size(); ++i) *it++ += *b++;
307 const_iterator b = other.begin(); iterator it = begin();
308 for (
size_type i=0; i < size(); ++i) *it++ -= *b++;
313 iterator it = begin(), ite=end();
314 while(it < ite) *it++ *= v;
320 return std::lexicographical_compare(begin(), end(), other.begin(), other.end());
322 void fill(T v) {
for (iterator it=begin(); it != end(); ++it) *it = v; }
324 #ifdef GETFEM_HAS_OPENMP
325 size_type memsize()
const {
return (size()*
sizeof(T)) +
sizeof(*this); }
327 size_type memsize()
const {
return (size()*
sizeof(T) / refcnt()) +
sizeof(*this); }
329 void push_back(T x) { resize(size()+1); begin()[size()-1] = x; }
333 allocator().duplicate_if_aliased(
id);
334 return static_cast<pointer
>(allocator().obj_data(
id));
337 const_pointer const_base()
const {
338 SVEC_ASSERT(
id == 0 || refcnt());
return static_cast<pointer
>(allocator().obj_data(
id));
341 return node_id(allocator().allocate(gmm::uint32_type(n*
sizeof(value_type)))); SVEC_ASSERT(refcnt() == 1);
348 const_iterator b = other.begin(); iterator it = begin();
349 for (
size_type i=0; i < size(); ++i) *it++ += v * *b++;
354 template<
class T> std::ostream& operator<<(std::ostream& os,
const small_vector<T>& v) {
355 os <<
"[";
for (
size_type i=0; i < v.size(); ++i) {
if (i) os <<
", "; os << v[i]; }
356 os <<
"]";
return os;
359 template<
class T>
inline small_vector<T> operator *(T x,
const small_vector<T>& m)
363 template <
class VEC_CONT>
364 void vectors_to_base_matrix(base_matrix &G,
const VEC_CONT &a) {
365 size_type P = (*(a.begin())).size(), NP = a.end() - a.begin();
366 G.base_resize(P, NP);
367 typename VEC_CONT::const_iterator it = a.begin(), ite = a.end();
368 base_matrix::iterator itm = G.begin();
369 for (; it != ite; ++it, itm += P)
370 std::copy((*it).begin(), (*it).end(), itm);
373 typedef small_vector<scalar_type> base_small_vector;
374 typedef base_small_vector base_node;
defines and typedefs for namespace bgeot
container for small vectors of POD (Plain Old Data) types.
A simple singleton implementation.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
interface for bgeot::small_vector
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
std::ostream & operator<<(std::ostream &o, const convex_structure &cv)
Print the details of the convex structure cvs to the output stream o.
size_t size_type
used as the common size type in the library