root/win32/itpp-4.0.1/itpp/base/factory.h @ 35

Revision 35, 7.5 kB (checked in by mido, 16 years ago)

zasadni zmeny ve /win32

RevLine 
[35]1/*!
2 * \file
3 * \brief Base class for class factories and memory allocation functions
4 * \author Johan Bergman and Adam Piatyszek
5 *
6 * -------------------------------------------------------------------------
7 *
8 * IT++ - C++ library of mathematical, signal processing, speech processing,
9 *        and communications classes and functions
10 *
11 * Copyright (C) 1995-2007  (see AUTHORS file for a list of contributors)
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 *
27 * -------------------------------------------------------------------------
28 */
29
30#ifndef FACTORY_H
31#define FACTORY_H
32
33#include <complex>
34#include <itpp/base/binary.h>
35
36namespace itpp {
37
38  // Forward declarations
39  template<class T> class Array;
40  template<class Num_T> class Mat;
41  template<class Num_T> class Vec;
42
43  /*!
44    \brief Base class for class factories
45
46    A class factory (or virtual constructor) is a class that can create instances
47    of another class. Factory is a base class for such factories. When declaring
48    an Array, Vec or Mat, a factory can be passed as an (optional) constructor
49    argument:
50    \code
51    // Declare a Vec<type> with size=10 and factory=DEFAULT_FACTORY
52    Vec<type> a(10);
53
54    // Declare a Vec<type> with size=10 and factory=f
55    Factory f;
56    Vec<type> b(10, f);
57    \endcode
58
59    By default, the factory (\c DEFAULT_FACTORY and \c f in the above examples)
60    is not used at all! However, by overloading a help function called
61    \e create_elements we can force Array/Vec/Mat to use the factory for element
62    creation (instead of using the default constructor for the element type).
63
64    \note It is the \e numeric elements that will be created by the factory,
65    i.e. for an Array<Mat<T> >, the factory will be used for creating the Mat
66    elements rather than the Array elements.
67
68    Here is an example that (partly) defines a user-defined numeric type My_Type,
69    a corresponding factory My_Factory and a corresponding help function
70    create_elements<My_Type> that will be used by Array, Vec and Mat for element
71    creation.
72    \code
73    class My_Type {
74    public:
75    // Default constructor
76    My_Type() : data(0) {}
77    // Constructor
78    My_Type(int d) : data(d) {}
79    .
80    .
81    .
82    protected:
83    int data;
84    };
85
86    class My_Factory : public Factory {
87    public:
88    // Constructor
89    explicit My_Factory(int d) : init_data(d) {}
90    // Destructor
91    virtual ~My_Factory() {}
92    // Create an n-length array of My_Type
93    virtual void create(My_Type* &ptr, int n) const {ptr = new My_Type[n](init_data);}
94    protected:
95    int init_data;
96    };
97
98    // Create an n-length array of My_Type using My_Factory f
99    template<>
100    void create_elements<My_Type>(My_Type* &ptr, int n, const Factory &f)
101    {
102    if (const My_Factory *my_factory_ptr = dynamic_cast<const My_Factory*>(&f)) {
103    // Yes, f seems to be a My_Factory. Now call the My_Factory::create method
104    my_factory_ptr->create(ptr, n);
105    }
106    else {
107    // No, f does not seem to be a My_Factory. As a fallback solution,
108    // assume that f is DEFAULT_FACTORY and use the default constructor
109    ptr = new My_Type[n];
110    }
111    }
112    \endcode
113
114    Now,
115    \code
116    // Declare a My_Factory for init_data = 123
117    My_Factory my123_factory(123);
118
119    // Declare a Vec<My_Type> with size 10 that uses My_Type() for element creation
120    Vec<My_Type> v1(10);
121
122    // Declare a Vec<My_Type> with size 10 that uses My_Type(123) for element creation
123    Vec<My_Type> v1(10, my123_factory);
124    \endcode
125
126    For a more interesting example, see Fix_Factory.
127  */
128  class Factory {
129  public:
130    //! Default constructor
131    Factory() {}
132    //! Destructor
133    virtual ~Factory() {}
134  };
135
136  //! Default (dummy) factory
137  const Factory DEFAULT_FACTORY;
138
139
140  //! Create an n-length array of T to be used as Array, Vec or Mat elements
141  template<class T>
142  void create_elements(T* &ptr, int n, const Factory &)
143  {
144    void *p = operator new(sizeof(T) * n);
145    ptr = reinterpret_cast<T*>(p);
146    for (int i = 0; i < n; i++) {
147      new (ptr + i) T();
148    }
149  }
150
151
152  //! Specialization for unsigned char data arrays (used in GF2Mat)
153  template<>
154  void create_elements<unsigned char>(unsigned char* &ptr, int n,
155                                      const Factory &);
156  //! Specialization for binary data arrays
157  template<>
158  void create_elements<bin>(bin* &ptr, int n, const Factory &);
159  //! Specialization for short integer data arrays
160  template<>
161  void create_elements<short int>(short int* &ptr, int n, const Factory &);
162  //! Specialization for integer data arrays
163  template<>
164  void create_elements<int>(int* &ptr, int n, const Factory &);
165  //! Specialization for 16-byte aligned double data arrays
166  template<>
167  void create_elements<double>(double* &ptr, int n, const Factory &);
168  //! Specialization for 16-byte aligned complex double data arrays
169  template<>
170  void create_elements<std::complex<double> >(std::complex<double>* &ptr, int n, const Factory &);
171
172
173  //! Destroy an array of Array, Vec or Mat elements
174  template<class T>
175  void destroy_elements(T* &ptr, int n)
176  {
177    if (ptr) {
178      for (int i = 0; i < n; ++i) {
179        ptr[i].~T();
180      }
181      void *p = reinterpret_cast<void*>(ptr);
182      operator delete(p);
183      ptr = 0;
184    }
185  }
186
187  //! Specialization for unsigned char data arrays (used in GF2Mat)
188  template<>
189  void destroy_elements<unsigned char>(unsigned char* &ptr, int n);
190  //! Specialization for binary data arrays
191  template<>
192  void destroy_elements<bin>(bin* &ptr, int n);
193  //! Specialization for short integer data arrays
194  template<>
195  void destroy_elements<short int>(short int* &ptr, int n);
196  //! Specialization for integer data arrays
197  template<>
198  void destroy_elements<int>(int* &ptr, int n);
199  //! Specialisation for 16-byte aligned double data arrays
200  template<>
201  void destroy_elements<double>(double* &ptr, int n);
202  //! Specialisation for 16-byte aligned complex double data arrays
203  template<>
204  void destroy_elements<std::complex<double> >(std::complex<double>* &ptr,
205                                               int n);
206
207
208  //! Create an n-length array of Array<T> to be used as Array elements
209  template<class T>
210  void create_elements(Array<T>* &ptr, int n, const Factory &f)
211  {
212    void *p = operator new(sizeof(Array<T>) * n);
213    ptr = reinterpret_cast<Array<T>*>(p);
214    for (int i = 0; i < n; ++i) {
215      new (ptr + i) Array<T>(f);
216    }
217  }
218
219  //! Create an n-length array of Mat<T> to be used as Array elements
220  template<class T>
221  void create_elements(Mat<T>* &ptr, int n, const Factory &f)
222  {
223    void *p = operator new(sizeof(Mat<T>) * n);
224    ptr = reinterpret_cast<Mat<T>*>(p);
225    for (int i = 0; i < n; ++i) {
226      new (ptr + i) Mat<T>(f);
227    }
228  }
229
230  //! Create an n-length array of Vec<T> to be used as Array elements
231  template<class T>
232  void create_elements(Vec<T>* &ptr, int n, const Factory &f)
233  {
234    void *p = operator new(sizeof(Vec<T>) * n);
235    ptr = reinterpret_cast<Vec<T>*>(p);
236    for (int i = 0; i < n; ++i) {
237      new (ptr + i) Vec<T>(f);
238    }
239  }
240
241} // namespace itpp
242
243#endif // #ifndef FACTORY_H
Note: See TracBrowser for help on using the browser.