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 protected:
144  virtual ObjectProtocol *invalid(void) const;
145 
146 public:
150  static const vectorsize_t npos;
151 
155  Vector();
156 
161  Vector(vectorsize_t size);
162 
172  Vector(ObjectProtocol **items, vectorsize_t size = 0);
173 
177  virtual ~Vector();
178 
183  vectorsize_t len(void) const;
184 
190  vectorsize_t size(void) const;
191 
197  ObjectProtocol *get(int index) const;
198 
205  vectorsize_t get(void **mem, vectorsize_t max) const;
206 
212  ObjectProtocol *begin(void) const;
213 
219  ObjectProtocol *end(void) const;
220 
227  vectorsize_t find(ObjectProtocol *pointer, vectorsize_t offset = 0) const;
228 
234  void split(vectorsize_t position);
235 
242  void rsplit(vectorsize_t position);
243 
250  void set(vectorsize_t position, ObjectProtocol *pointer);
251 
256  void set(ObjectProtocol **list);
257 
262  void add(ObjectProtocol **list);
263 
268  void add(ObjectProtocol *pointer);
269 
273  void clear(void);
274 
279  virtual bool resize(vectorsize_t size);
280 
285  inline void set(Vector &vector)
286  {set(vector.list());};
287 
292  inline void add(Vector &vector)
293  {add(vector.list());};
294 
299  inline ObjectProtocol *operator[](int index)
300  {return get(index);};
301 
307  inline void operator()(vectorsize_t position, ObjectProtocol *pointer)
308  {set(position, pointer);};
309 
315  inline ObjectProtocol *operator()(vectorsize_t position)
316  {return get(position);};
317 
322  inline void operator()(ObjectProtocol *pointer)
323  {add(pointer);};
324 
329  inline void operator=(Vector &vector)
330  {set(vector.list());};
331 
336  inline void operator+=(Vector &vector)
337  {add(vector.list());};
338 
343  inline Vector& operator+(Vector &vector)
344  {add(vector.list()); return *this;};
345 
350  Vector &operator^(Vector &vector);
351 
358  void operator^=(Vector &vector);
359 
363  void operator++();
364 
368  void operator--();
369 
374  void operator+=(vectorsize_t count);
375 
380  void operator-=(vectorsize_t count);
381 
387  static vectorsize_t size(void **list);
388 };
389 
395 class __EXPORT MemVector : public Vector
396 {
397 private:
398  bool resize(vectorsize_t size);
399  void cow(vectorsize_t adj = 0);
400  void release(void);
401 
402  friend class Vector::array;
403 
404 public:
410  MemVector(void *pointer, vectorsize_t size);
411 
415  ~MemVector();
416 
421  inline void operator=(Vector &vector)
422  {set(vector);};
423 
424 };
425 
431 template<class T>
432 class vectorof : public Vector
433 {
434 public:
438  inline vectorof() : Vector() {};
439 
444  inline vectorof(vectorsize_t size) : Vector(size) {};
445 
446  inline T& operator[](int index)
447  {return static_cast<T&>(Vector::get(index));};
448 
449  inline const T& at(int index)
450  {return static_cast<const T&>(Vector::get(index));};
451 
457  inline T *operator()(vectorsize_t position)
458  {return static_cast<T *>(Vector::get(position));};
459 
464  inline T *begin(void)
465  {return static_cast<T *>(Vector::begin());};
466 
471  inline T *end(void)
472  {return static_cast<T *>(Vector::end());};
473 
479  inline Vector &operator+(Vector &vector)
480  {Vector::add(vector); return static_cast<Vector &>(*this);};
481 };
482 
489 template<class T>
490 class array_reuse : protected ArrayReuse
491 {
492 public:
497  inline array_reuse(unsigned count) :
498  ArrayReuse(sizeof(T), count) {};
499 
504  inline operator bool() const
505  {return avail();};
506 
511  inline bool operator!() const
512  {return !avail();};
513 
518  inline T* request(void)
519  {return static_cast<T*>(ArrayReuse::request());};
520 
526  inline T* get(void)
527  {return static_cast<T*>(ArrayReuse::get());};
528 
534  inline T* create(void)
535  {return init<T>(static_cast<T*>(ArrayReuse::get()));};
536 
543  inline T* get(timeout_t timeout)
544  {return static_cast<T*>(ArrayReuse::get(timeout));};
545 
552  inline T* create(timeout_t timeout)
553  {return init<T>(static_cast<T*>(ArrayReuse::get(timeout)));};
554 
559  inline void release(T *object)
560  {ArrayReuse::release(object);};
561 
567  inline operator T*()
568  {return array_reuse::get();};
569 
575  inline T *operator*()
576  {return array_reuse::get();};
577 };
578 
585 template <class T>
586 class paged_reuse : protected PagerReuse
587 {
588 public:
596  inline paged_reuse(mempager *pager, unsigned count) :
597  PagerReuse(pager, sizeof(T), count) {};
598 
603  inline operator bool() const
604  {return PagerReuse::avail();};
605 
610  inline bool operator!() const
611  {return !PagerReuse::avail();};
612 
618  inline T *get(void)
619  {return static_cast<T*>(PagerReuse::get());};
620 
627  inline T *create(void)
628  {return init<T>(static_cast<T*>(PagerReuse::get()));};
629 
636  inline T *get(timeout_t timeout)
637  {return static_cast<T*>(PagerReuse::get(timeout));};
638 
646  inline T *create(timeout_t timeout)
647  {return init<T>(static_cast<T*>(PagerReuse::get(timeout)));};
648 
653  inline T *request(void)
654  {return static_cast<T*>(PagerReuse::request());};
655 
660  inline void release(T *object)
661  {PagerReuse::release(object);};
662 
668  inline T *operator*()
669  {return paged_reuse::get();};
670 
676  inline operator T*()
677  {return paged_reuse::get();};
678 };
679 
687 template<typename T, vectorsize_t S>
688 class vectorbuf : public MemVector
689 {
690 private:
691  char buffer[sizeof(array) + (S * sizeof(void *))];
692 
693 public:
697  inline vectorbuf() : MemVector(buffer, S) {};
698 
704  inline const T& at(int index)
705  {return static_cast<const T&>(Vector::get(index));};
706 
707  inline T& operator[](int index)
708  {return static_cast<T&>(Vector::get(index));};
709 
715  inline T *operator()(vectorsize_t position)
716  {return static_cast<T *>(Vector::get(position));};
717 
722  inline T *begin(void)
723  {return static_cast<T *>(Vector::begin());};
724 
729  inline T *end(void)
730  {return static_cast<T *>(Vector::end());};
731 
737  inline Vector &operator+(Vector &vector)
738  {Vector::add(vector); return static_cast<Vector &>(*this);};
739 };
740 
741 END_NAMESPACE
742 
743 #endif