37 #ifndef BGEOT_SMALL_VECTOR_H 38 #define BGEOT_SMALL_VECTOR_H 42 #ifdef DEBUG_SMALL_VECTOR 44 # define SVEC_ASSERT(x) assert(x) 46 # define SVEC_ASSERT(x) 51 class APIDECL block_allocator {
53 typedef gmm::uint16_type uint16_type;
54 typedef gmm::uint32_type node_id;
57 enum { p2_BLOCKSZ = 8, BLOCKSZ = 1<<p2_BLOCKSZ };
58 enum { OBJ_SIZE_LIMIT = 129 };
59 enum { MAXREF = 256 };
66 uint16_type first_unused_chunk, count_unused_chunk;
68 size_type prev_unfilled, next_unfilled;
71 block(size_type objsz_) : data(0),
72 prev_unfilled(size_type(-1)),
73 next_unfilled(size_type(-1)),
80 data =
static_cast<unsigned char*
>(::operator
new(BLOCKSZ*objsz + BLOCKSZ));
82 memset(data, 0, BLOCKSZ);
87 if (data) { ::operator
delete(data); };
88 data = 0; first_unused_chunk = 0; count_unused_chunk = BLOCKSZ;
90 unsigned char& refcnt(size_type pos) {
return data[pos]; }
91 bool empty()
const {
return data == 0; }
96 std::vector<block> blocks;
98 size_type first_unfilled[OBJ_SIZE_LIMIT];
103 void * obj_data(node_id
id) {
104 return blocks[
id/BLOCKSZ].data + BLOCKSZ + (
id%BLOCKSZ)*blocks[
id/BLOCKSZ].objsz;
106 dim_type obj_sz(node_id
id) {
107 return dim_type(blocks[
id/BLOCKSZ].objsz);
110 unsigned char& refcnt(node_id
id) {
111 return blocks[
id/BLOCKSZ].refcnt(
id%BLOCKSZ);
113 node_id inc_ref(node_id
id) {
114 if (
id && ++refcnt(
id) == 0) {
120 void dec_ref(node_id
id) {
121 SVEC_ASSERT(
id==0 || refcnt(
id));
122 if (
id && --refcnt(
id) == 0) {
127 void duplicate_if_aliased(node_id&
id) {
128 if (refcnt(
id) != 1) {
130 id = duplicate(
id); SVEC_ASSERT(
id == 0 || refcnt(
id)==1);
136 void deallocate(node_id nid);
140 node_id duplicate(node_id
id) {
141 node_id id2 = allocate(obj_sz(
id));
142 memcpy(obj_data(id2),obj_data(
id),obj_sz(
id));
150 struct APIDECL static_block_allocator {
153 static block_allocator *palloc;
157 #if !defined GETFEM_HAVE_OPENMP 162 template<
typename T>
class small_vector :
public static_block_allocator {
163 typedef block_allocator::node_id node_id;
168 typedef T value_type;
170 typedef const T * const_pointer;
171 typedef T& reference;
172 typedef const T & const_reference;
174 typedef const T * const_iterator;
176 reference operator[](size_type l)
177 { GMM_ASSERT2(l <=size(),
"out of range, l="<<l<<
"size="<<size());
return base()[l]; }
178 value_type operator[](size_type l)
const 179 { GMM_ASSERT2(l <= size(),
"out of range, l="<<l<<
"size="<<size());
return const_base()[l]; }
180 value_type at(size_type l)
const {
return const_base()[l]; }
181 iterator begin() {
return base(); }
182 const_iterator begin()
const {
return const_base(); }
183 const_iterator const_begin()
const {
return const_base(); }
184 iterator end() {
return base()+size(); }
185 const_iterator end()
const {
return const_base()+size(); }
186 const_iterator const_end()
const {
return const_base()+size(); }
187 void resize(size_type n) {
188 if (n == size())
return;
191 memcpy(other.base(), const_base(), std::min(size(),other.size())*
sizeof(value_type));
192 SVEC_ASSERT(
id==0 || refcnt());
194 SVEC_ASSERT(refcnt()); SVEC_ASSERT(other.id == 0 || other.refcnt());
195 }
else { allocator().dec_ref(
id);
id=0; }
199 node_id id2 = allocator().inc_ref(other.id);
200 allocator().dec_ref(
id);
id = id2;
201 SVEC_ASSERT(
id == 0 || refcnt()); SVEC_ASSERT(other.id == 0 || other.refcnt());
208 explicit small_vector(
const std::vector<T>& v) : id(allocate(v.size())) {
209 std::copy(v.begin(),v.end(),begin());
216 if (!allocator_destroyed())
217 allocator().dec_ref(
id);
221 { begin()[0] = v1; begin()[1] = v2; }
223 { begin()[0] = v1; begin()[1] = v2; begin()[2] = v3; }
225 : id(allocate(a.size())) { std::transform(a.begin(), a.end(), begin(), op); }
227 : id(allocate(a.size())) { std::transform(a.begin(), a.end(), b.begin(), begin(), op); }
228 bool empty()
const {
return id==0; }
229 unsigned char refcnt()
const {
return allocator().refcnt(
id); }
230 dim_type size()
const 231 {
return dim_type(allocator().obj_sz(
id)/
sizeof(value_type)); }
237 {
return -1.*(*this); }
239 {
return small_vector<T>(*
this, std::bind2nd(std::multiplies<T>(),v)); }
242 const_iterator b = other.begin(); iterator it = begin();
243 for (size_type i=0; i < size(); ++i) *it++ += *b++;
249 const_iterator b = other.begin(); iterator it = begin();
250 for (size_type i=0; i < size(); ++i) *it++ -= *b++;
253 small_vector<T> operator*=(T v) { iterator it = begin(), ite=end();
while(it < ite) *it++ *= v;
return *
this; }
255 bool operator<(const small_vector<T>& other)
const;
256 void fill(T v) {
for (iterator it=begin(); it != end(); ++it) *it = v; }
259 void push_back(T x) { resize(size()+1); begin()[size()-1] = x; }
260 size_type memsize()
const {
return (size()*
sizeof(T) / refcnt()) +
sizeof(*this); }
264 allocator().duplicate_if_aliased(
id);
265 return static_cast<pointer
>(allocator().obj_data(
id));
268 const_pointer const_base()
const {
269 SVEC_ASSERT(
id == 0 || refcnt());
return static_cast<pointer
>(allocator().obj_data(
id));
271 block_allocator& allocator()
const {
return *palloc; }
272 bool allocator_destroyed()
const {
return palloc == 0; }
273 node_id allocate(size_type n) {
274 return node_id(allocator().allocate(gmm::uint32_type(n*
sizeof(value_type)))); SVEC_ASSERT(refcnt() == 1);
280 return std::lexicographical_compare(begin(), end(), other.begin(), other.end());
285 const_iterator b = other.begin(); iterator it = begin();
286 for (size_type i=0; i < size(); ++i) *it++ += v * *b++;
295 template<
typename T>
class small_vector :
public std::vector<T>
298 typedef typename std::vector<T>::const_iterator const_iterator;
299 typedef typename std::vector<T>::iterator iterator;
301 const_iterator const_begin()
const {
return std::vector<T>::begin();}
302 const_iterator const_end()
const {
return std::vector<T>::end(); }
306 explicit small_vector(size_type n) : std::vector<T>(n) {}
310 small_vector(
const std::vector<T>& v) : std::vector<T>(v) {}
313 { (*this)[0] = v1; (*this)[1] = v2; }
316 { (*this)[0] = v1; (*this)[1] = v2; (*this)[2] = v3; }
319 : std::vector<T>(a.size())
320 { std::transform(a.begin(), a.end(), std::vector<T>::begin(), op); }
323 : std::vector<T>(a.size())
324 { std::transform(a.begin(), a.end(), b.begin(), std::vector<T>::begin(), op); }
333 {
return -1.*(*this); }
336 {
return small_vector<T>(*
this, std::bind2nd(std::multiplies<T>(),v)); }
342 const_iterator b = other.begin(); iterator it = std::vector<T>::begin();
343 for (size_type i=0; i < std::vector<T>::size(); ++i) *it++ += *b++;
351 const_iterator b = other.begin(); iterator it = std::vector<T>::begin();
352 for (size_type i=0; i < std::vector<T>::size(); ++i) *it++ -= *b++;
358 iterator it = std::vector<T>::begin(), ite=std::vector<T>::end();
359 while(it < ite) *it++ *= v;
365 void fill(T v) {
for (iterator it=std::vector<T>::begin(); it != std::vector<T>::end(); ++it) *it = v; }
367 size_type memsize()
const {
return (std::vector<T>::size()*
sizeof(T)) +
sizeof(*this); }
368 inline bool operator<(const small_vector<T>& other)
const 370 return std::lexicographical_compare(std::vector<T>::begin(), std::vector<T>::end(), other.begin(), other.end());
376 const_iterator b = other.begin(); iterator it = std::vector<T>::begin();
377 for (size_type i=0; i < std::vector<T>::size(); ++i) *it++ += v * *b++;
382 #endif // #if !defined GETFEM_HAVE_OPENMP 385 template<
class T> std::ostream& operator<<(std::ostream& os, const small_vector<T>& v) {
386 os <<
"[";
for (size_type i=0; i < v.size(); ++i) {
if (i) os <<
", "; os << v[i]; }
387 os <<
"]";
return os;
394 template <
class VEC_CONT>
395 void vectors_to_base_matrix(base_matrix &G,
const VEC_CONT &a) {
396 size_type P = (*(a.begin())).size(), NP = a.end() - a.begin();
397 G.base_resize(P, NP);
398 typename VEC_CONT::const_iterator it = a.begin(), ite = a.end();
399 base_matrix::iterator itm = G.begin();
400 for (; it != ite; ++it, itm += P)
401 std::copy((*it).begin(), (*it).end(), itm);
container for small vectors of POD (Plain Old Data) types.
std::ostream & operator<<(std::ostream &o, const convex_structure &cv)
Print the details of the convex structure cvs to the output stream o.
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
static T & instance()
Instance from the current thread.
size_t size_type
used as the common size type in the library
A simple singleton implementation.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
interface for bgeot::small_vector
defines and typedefs for namespace bgeot