[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

memory.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2002-2003 by Ullrich Koethe, Hans Meine */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_MEMORY_HXX
37 #define VIGRA_MEMORY_HXX
38 
39 
40 #include "config.hxx"
41 
42 #ifdef VIGRA_SHARED_PTR_IN_TR1
43 # include <tr1/memory>
44 #else
45 # include <memory>
46 #endif
47 
48 #include <cstring>
49 #include "metaprogramming.hxx"
50 
51 namespace vigra {
52 
53 enum SkipInitializationTag { SkipInitialization};
54 
55 template<class T>
56 struct CanSkipInitialization
57 {
58  typedef typename TypeTraits<T>::isBuiltinType type;
59  static const bool value = type::asBool;
60 };
61 
62 namespace detail {
63 
64 // differs from std::uninitialized_copy by explicit type conversion
65 template <class Src, class Dest>
66 Dest uninitializedCopy(Src s, Src end, Dest d)
67 {
68  typedef typename std::iterator_traits<Dest>::value_type T;
69  for(; s != end; ++s, ++d)
70  new(d) T(static_cast<T const &>(*s));
71  return d;
72 }
73 
74 template <class T>
75 struct PlacementNewAllocator
76 {
77  T * allocate(std::size_t n)
78  {
79  return (T*)::operator new(n*sizeof(T));
80  }
81 
82  void deallocate(T * p, std::size_t)
83  {
84  return ::operator delete(p);
85  }
86 
87  void construct(T * p, T const & initial)
88  {
89  new(p) T(initial);
90  }
91 
92  void destroy(T * p)
93  {
94  p->~T();
95  }
96 };
97 
98 template <class T>
99 inline void
100 destroy_n(T * /* p */, std::size_t /* n */, VigraTrueType /* isPOD */)
101 {}
102 
103 template <class T>
104 inline void
105 destroy_n(T * p, std::size_t n, VigraFalseType /* isPOD */)
106 {
107  for(std::size_t i=0; i < n; ++i, ++p)
108  p->~T();
109 }
110 
111 template <class T>
112 inline void
113 destroy_n(T * p, std::size_t n)
114 {
115  destroy_n(p, n, typename TypeTraits<T>::isPOD());
116 }
117 
118 template <class T, class Alloc>
119 inline T *
120 alloc_initialize_n(std::size_t n, T const & initial, Alloc & alloc)
121 {
122  T * p = alloc.allocate(n);
123  bool useMemset = TypeTraits<T>::isPOD::value &&
124  (initial == T());
125  if(useMemset)
126  {
127  std::memset(p, 0, n*sizeof(T));
128  }
129  else
130  {
131  std::size_t i=0;
132  try
133  {
134  for (; i < n; ++i)
135  alloc.construct(p+i, initial);
136  }
137  catch (...)
138  {
139  for (std::size_t j=0; j < i; ++j)
140  alloc.destroy(p+j);
141  alloc.deallocate(p, n);
142  throw;
143  }
144  }
145  return p;
146 }
147 
148 template <class T>
149 inline T *
150 alloc_initialize_n(std::size_t n, T const & initial)
151 {
152  PlacementNewAllocator<T> alloc;
153  return alloc_initialize_n<T>(n, initial, alloc);
154 }
155 
156 template <class T>
157 inline T *
158 alloc_initialize_n(std::size_t n)
159 {
160  PlacementNewAllocator<T> alloc;
161  return alloc_initialize_n<T>(n, T(), alloc);
162 }
163 
164 template <class T, class Alloc>
165 inline void
166 destroy_dealloc_impl(T * p, std::size_t n, Alloc & alloc, VigraTrueType /* isPOD */)
167 {
168  alloc.deallocate(p, n);
169 }
170 
171 template <class T, class Alloc>
172 inline void
173 destroy_dealloc_impl(T * p, std::size_t n, Alloc & alloc, VigraFalseType /* isPOD */)
174 {
175  for (std::size_t i=0; i < n; ++i)
176  alloc.destroy(p + i);
177  alloc.deallocate(p, n);
178 }
179 
180 template <class T, class Alloc>
181 inline T *
182 destroy_dealloc_n(T * p, std::size_t n, Alloc & alloc)
183 {
184  if(p != 0)
185  destroy_dealloc_impl(p, n, alloc, typename TypeTraits<T>::isPOD());
186  return 0;
187 }
188 
189 template <class T>
190 inline T *
191 destroy_dealloc_n(T * p, std::size_t n)
192 {
193  if(p != 0)
194  {
195  PlacementNewAllocator<T> alloc;
196  destroy_dealloc_impl(p, n, alloc, typename TypeTraits<T>::isPOD());
197  }
198  return 0;
199 }
200 
201 /********************************************************************/
202 
203 // g++ 2.95 has std::destroy() in the STL
204 #if !defined(__GNUC__) || __GNUC__ >= 3
205 
206 template <class T>
207 inline void destroy(T * /* p */, VigraTrueType /* isPOD */)
208 {
209 }
210 
211 template <class T>
212 inline void destroy(T * p, VigraFalseType /* isPOD */)
213 {
214  p->~T();
215 }
216 
217 template <class T>
218 inline void destroy(T * p)
219 {
220  destroy(p, typename TypeTraits<T>::isPOD());
221 }
222 
223 #else
224 
225 } } // namespace vigra::detail
226 
227 #include <memory>
228 
229 namespace vigra { namespace detail {
230 
231 using std::destroy;
232 
233 #endif
234 
235 } } // namespace vigra::detail
236 
237 #endif // VIGRA_MEMORY_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)