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;
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;
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 class APIDECL static_block_allocator {
153 static block_allocator *palloc;
155 static_block_allocator();
157 block_allocator& allocator()
const;
158 bool allocator_destroyed()
const;
162 #ifdef GETFEM_HAS_OPENMP
165 template<
typename T>
class small_vector :
public std::vector<T>
168 using typename std::vector<T>::const_iterator;
169 using typename std::vector<T>::iterator;
170 const_iterator begin()
const {
return std::vector<T>::begin(); }
171 iterator begin() {
return std::vector<T>::begin(); }
172 const_iterator end()
const {
return std::vector<T>::end(); }
173 iterator end() {
return std::vector<T>::end(); }
175 const_iterator const_begin()
const {
return std::vector<T>::cbegin(); }
176 const_iterator const_end()
const {
return std::vector<T>::cend(); }
177 dim_type size()
const {
return dim_type(std::vector<T>::size()); }
179 const small_vector<T>& operator=(
const small_vector<T>& other) {
180 std::vector<T>::operator=(other);
184 small_vector() : std::vector<T>() {}
186 explicit small_vector(
size_type n) : std::vector<T>(n) {}
188 small_vector(
const small_vector<T>& v) : std::vector<T>(v) {}
190 small_vector(
const std::vector<T>& v) : std::vector<T>(v) {}
192 small_vector(T v1, T v2) : std::vector<T>(2)
193 { (*this)[0] = v1; (*this)[1] = v2; }
195 small_vector(T v1, T v2, T v3) : std::vector<T>(3)
196 { (*this)[0] = v1; (*this)[1] = v2; (*this)[2] = v3; }
198 template<
class UNOP> small_vector(
const small_vector<T>& a, UNOP op)
199 : std::vector<T>(a.size())
200 { std::transform(a.begin(), a.end(), begin(), op); }
202 template<
class BINOP> small_vector(
const small_vector<T>& a,
const small_vector<T>& b, BINOP op)
203 : std::vector<T>(a.size())
204 { std::transform(a.begin(), a.end(), b.begin(), begin(), op); }
210 template<
typename T>
class small_vector :
public static_block_allocator {
211 typedef block_allocator::node_id node_id;
216 typedef T value_type;
218 typedef const T * const_pointer;
219 typedef T& reference;
220 typedef const T & const_reference;
222 typedef const T * const_iterator;
225 { GMM_ASSERT2(l <=size(),
"out of range, l="<<l<<
"size="<<size());
return base()[l]; }
227 { GMM_ASSERT2(l <= size(),
"out of range, l="<<l<<
"size="<<size());
return const_base()[l]; }
228 value_type at(
size_type l)
const {
return const_base()[l]; }
229 iterator begin() {
return base(); }
230 const_iterator begin()
const {
return const_base(); }
231 const_iterator const_begin()
const {
return const_base(); }
232 iterator end() {
return base()+size(); }
233 const_iterator end()
const {
return const_base()+size(); }
234 const_iterator const_end()
const {
return const_base()+size(); }
236 if (n == size())
return;
239 memcpy(other.base(), const_base(), std::min(size(),other.size())*
sizeof(value_type));
240 SVEC_ASSERT(
id==0 || refcnt());
242 SVEC_ASSERT(refcnt()); SVEC_ASSERT(other.id == 0 || other.refcnt());
243 }
else { allocator().dec_ref(
id);
id=0; }
247 node_id id2 = allocator().inc_ref(other.id);
248 allocator().dec_ref(
id);
id = id2;
249 SVEC_ASSERT(
id == 0 || refcnt()); SVEC_ASSERT(other.id == 0 || other.refcnt());
256 explicit small_vector(
const std::vector<T>& v) : id(allocate(v.size())) {
257 std::copy(v.begin(),v.end(),begin());
264 if (!allocator_destroyed())
265 allocator().dec_ref(
id);
269 { begin()[0] = v1; begin()[1] = v2; }
271 { begin()[0] = v1; begin()[1] = v2; begin()[2] = v3; }
273 : id(allocate(a.size())) { std::transform(a.begin(), a.end(), begin(), op); }
275 : id(allocate(a.size())) { std::transform(a.begin(), a.end(), b.begin(), begin(), op); }
276 bool empty()
const {
return id==0; }
277 unsigned char refcnt()
const {
return allocator().refcnt(
id); }
278 dim_type size()
const
279 {
return dim_type(allocator().obj_sz(
id)/
sizeof(value_type)); }
289 {
return -1.*(*this); }
296 const_iterator b = other.begin(); iterator it = begin();
297 for (
size_type i=0; i < size(); ++i) *it++ += *b++;
304 const_iterator b = other.begin(); iterator it = begin();
305 for (
size_type i=0; i < size(); ++i) *it++ -= *b++;
310 iterator it = begin(), ite=end();
311 while(it < ite) *it++ *= v;
317 return std::lexicographical_compare(begin(), end(), other.begin(), other.end());
319 void fill(T v) {
for (iterator it=begin(); it != end(); ++it) *it = v; }
321 #ifdef GETFEM_HAS_OPENMP
322 size_type memsize()
const {
return (size()*
sizeof(T)) +
sizeof(*this); }
324 size_type memsize()
const {
return (size()*
sizeof(T) / refcnt()) +
sizeof(*this); }
326 void push_back(T x) { resize(size()+1); begin()[size()-1] = x; }
330 allocator().duplicate_if_aliased(
id);
331 return static_cast<pointer
>(allocator().obj_data(
id));
334 const_pointer const_base()
const {
335 SVEC_ASSERT(
id == 0 || refcnt());
return static_cast<pointer
>(allocator().obj_data(
id));
338 return node_id(allocator().allocate(gmm::uint32_type(n*
sizeof(value_type)))); SVEC_ASSERT(refcnt() == 1);
345 const_iterator b = other.begin(); iterator it = begin();
346 for (
size_type i=0; i < size(); ++i) *it++ += v * *b++;
351 template<
class T> std::ostream& operator<<(std::ostream& os,
const small_vector<T>& v) {
352 os <<
"[";
for (
size_type i=0; i < v.size(); ++i) {
if (i) os <<
", "; os << v[i]; }
353 os <<
"]";
return os;
356 template<
class T>
inline small_vector<T> operator *(T x,
const small_vector<T>& m)
360 template <
class VEC_CONT>
361 void vectors_to_base_matrix(base_matrix &G,
const VEC_CONT &a) {
362 size_type P = (*(a.begin())).size(), NP = a.end() - a.begin();
363 G.base_resize(P, NP);
364 typename VEC_CONT::const_iterator it = a.begin(), ite = a.end();
365 base_matrix::iterator itm = G.begin();
366 for (; it != ite; ++it, itm += P)
367 std::copy((*it).begin(), (*it).end(), itm);
370 typedef small_vector<scalar_type> base_small_vector;
371 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