UCommon
vector.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
27 #ifndef _UCOMMON_VECTOR_H_
28 #define _UCOMMON_VECTOR_H_
29 
30 #ifndef _UCOMMON_THREAD_H_
31 #include <ucommon/thread.h>
32 #endif
33 
34 typedef unsigned short vectorsize_t;
35 
36 NAMESPACE_UCOMMON
37 
45 class __EXPORT ArrayReuse : public ReusableAllocator
46 {
47 private:
48  size_t objsize;
49  unsigned count, limit, used;
50  caddr_t mem;
51 
52 protected:
53  ArrayReuse(size_t objsize, unsigned c);
54 
55 public:
59  ~ArrayReuse();
60 
61 protected:
62  bool avail(void);
63 
64  ReusableObject *get(timeout_t timeout);
65  ReusableObject *get(void);
66  ReusableObject *request(void);
67 };
68 
76 class __EXPORT PagerReuse : protected MemoryRedirect, protected ReusableAllocator
77 {
78 private:
79  unsigned limit, count;
80  size_t osize;
81 
82 protected:
83  PagerReuse(mempager *pager, size_t objsize, unsigned count);
84  ~PagerReuse();
85 
86  bool avail(void);
87  ReusableObject *get(void);
88  ReusableObject *get(timeout_t timeout);
89  ReusableObject *request(void);
90 };
91 
107 class __EXPORT Vector
108 {
109 public:
110  class __EXPORT array : public CountedObject
111  {
112  public:
113 #pragma pack(1)
114  vectorsize_t max, len;
115  ObjectProtocol *list[1];
116 #pragma pack()
117 
118  array(vectorsize_t size);
119  void dealloc(void);
120  void set(ObjectProtocol **items);
121  void add(ObjectProtocol **list);
122  void add(ObjectProtocol *obj);
123  void purge(void);
124  void inc(vectorsize_t adj);
125  void dec(vectorsize_t adj);
126  };
127 
128 protected:
129  array *data;
130 
131  array *create(vectorsize_t size) const;
132 
133  virtual void release(void);
134  virtual void cow(vectorsize_t adj = 0);
135  ObjectProtocol **list(void) const;
136 
137  friend class Vector::array;
138 
139 public:
143  static const vectorsize_t npos;
144 
148  Vector();
149 
154  Vector(vectorsize_t size);
155 
165  Vector(ObjectProtocol **items, vectorsize_t size = 0);
166 
170  virtual ~Vector();
171 
176  vectorsize_t len(void) const;
177 
183  vectorsize_t size(void) const;
184 
190  ObjectProtocol *get(int index) const;
191 
198  vectorsize_t get(void **mem, vectorsize_t max) const;
199 
205  ObjectProtocol *begin(void) const;
206 
212  ObjectProtocol *end(void) const;
213 
220  vectorsize_t find(ObjectProtocol *pointer, vectorsize_t offset = 0) const;
221 
227  void split(vectorsize_t position);
228 
235  void rsplit(vectorsize_t position);
236 
243  void set(vectorsize_t position, ObjectProtocol *pointer);
244 
249  void set(ObjectProtocol **list);
250 
255  void add(ObjectProtocol **list);
256 
261  void add(ObjectProtocol *pointer);
262 
266  void clear(void);
267 
272  virtual bool resize(vectorsize_t size);
273 
278  inline void set(Vector &vector)
279  {set(vector.list());};
280 
285  inline void add(Vector &vector)
286  {add(vector.list());};
287 
292  inline ObjectProtocol *operator[](int index)
293  {return get(index);};
294 
300  inline void operator()(vectorsize_t position, ObjectProtocol *pointer)
301  {set(position, pointer);};
302 
308  inline ObjectProtocol *operator()(vectorsize_t position)
309  {return get(position);};
310 
315  inline void operator()(ObjectProtocol *pointer)
316  {add(pointer);};
317 
322  inline void operator=(Vector &vector)
323  {set(vector.list());};
324 
329  inline void operator+=(Vector &vector)
330  {add(vector.list());};
331 
336  inline Vector& operator+(Vector &vector)
337  {add(vector.list()); return *this;};
338 
343  Vector &operator^(Vector &vector);
344 
351  void operator^=(Vector &vector);
352 
356  void operator++();
357 
361  void operator--();
362 
367  void operator+=(vectorsize_t count);
368 
373  void operator-=(vectorsize_t count);
374 
380  static vectorsize_t size(void **list);
381 };
382 
388 class __EXPORT MemVector : public Vector
389 {
390 private:
391  bool resize(vectorsize_t size);
392  void cow(vectorsize_t adj = 0);
393  void release(void);
394 
395  friend class Vector::array;
396 
397 public:
403  MemVector(void *pointer, vectorsize_t size);
404 
408  ~MemVector();
409 
414  inline void operator=(Vector &vector)
415  {set(vector);};
416 
417 };
418 
424 template<class T>
425 class vectorof : public Vector
426 {
427 public:
431  inline vectorof() : Vector() {};
432 
437  inline vectorof(vectorsize_t size) : Vector(size) {};
438 
444  inline T *get(int index)
445  {return static_cast<T *>(Vector::get(index));};
446 
447  inline T& operator[](int index)
448  {return static_cast<T *>(Vector::get(index));};
449 
455  inline T *operator()(vectorsize_t position)
456  {return static_cast<T *>(Vector::get(position));};
457 
462  inline T *begin(void)
463  {return static_cast<T *>(Vector::begin());};
464 
469  inline T *end(void)
470  {return static_cast<T *>(Vector::end());};
471 
477  inline Vector &operator+(Vector &vector)
478  {Vector::add(vector); return static_cast<Vector &>(*this);};
479 };
480 
487 template<class T>
488 class array_reuse : protected ArrayReuse
489 {
490 public:
495  inline array_reuse(unsigned count) :
496  ArrayReuse(sizeof(T), count) {};
497 
502  inline operator bool() const
503  {return avail();};
504 
509  inline bool operator!() const
510  {return !avail();};
511 
516  inline T* request(void)
517  {return static_cast<T*>(ArrayReuse::request());};
518 
524  inline T* get(void)
525  {return static_cast<T*>(ArrayReuse::get());};
526 
532  inline T* create(void)
533  {return init<T>(static_cast<T*>(ArrayReuse::get()));};
534 
541  inline T* get(timeout_t timeout)
542  {return static_cast<T*>(ArrayReuse::get(timeout));};
543 
550  inline T* create(timeout_t timeout)
551  {return init<T>(static_cast<T*>(ArrayReuse::get(timeout)));};
552 
557  inline void release(T *object)
558  {ArrayReuse::release(object);};
559 
565  inline operator T*()
566  {return array_reuse::get();};
567 
573  inline T *operator*()
574  {return array_reuse::get();};
575 };
576 
583 template <class T>
584 class paged_reuse : protected PagerReuse
585 {
586 public:
594  inline paged_reuse(mempager *pager, unsigned count) :
595  PagerReuse(pager, sizeof(T), count) {};
596 
601  inline operator bool() const
602  {return PagerReuse::avail();};
603 
608  inline bool operator!() const
609  {return !PagerReuse::avail();};
610 
616  inline T *get(void)
617  {return static_cast<T*>(PagerReuse::get());};
618 
625  inline T *create(void)
626  {return init<T>(static_cast<T*>(PagerReuse::get()));};
627 
634  inline T *get(timeout_t timeout)
635  {return static_cast<T*>(PagerReuse::get(timeout));};
636 
644  inline T *create(timeout_t timeout)
645  {return init<T>(static_cast<T*>(PagerReuse::get(timeout)));};
646 
651  inline T *request(void)
652  {return static_cast<T*>(PagerReuse::request());};
653 
658  inline void release(T *object)
659  {PagerReuse::release(object);};
660 
666  inline T *operator*()
667  {return paged_reuse::get();};
668 
674  inline operator T*()
675  {return paged_reuse::get();};
676 };
677 
685 template<typename T, vectorsize_t S>
686 class vectorbuf : public MemVector
687 {
688 private:
689  char buffer[sizeof(array) + (S * sizeof(void *))];
690 
691 public:
695  inline vectorbuf() : MemVector(buffer, S) {};
696 
702  inline T *get(int index)
703  {return static_cast<T *>(Vector::get(index));};
704 
705  inline T& operator[](int index)
706  {return static_cast<T*>(Vector::get(index));};
707 
713  inline T *operator()(vectorsize_t position)
714  {return static_cast<T *>(Vector::get(position));};
715 
720  inline T *begin(void)
721  {return static_cast<T *>(Vector::begin());};
722 
727  inline T *end(void)
728  {return static_cast<T *>(Vector::end());};
729 
735  inline Vector &operator+(Vector &vector)
736  {Vector::add(vector); return static_cast<Vector &>(*this);};
737 };
738 
739 END_NAMESPACE
740 
741 #endif