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