1 #ifndef YASLI_MEMORY_H_
2 #define YASLI_MEMORY_H_
4 // $Id: yasli_memory.h 754 2006-10-17 19:59:11Z syntheticpp $
7 #include "yasli_traits.h"
8 #include "yasli_protocols.h"//!
11 #include <misc/mojo.h>//NOT A SAFE WAY TO INCLUDE IT
17 // 20.4.1, the default allocator:
18 template <class T> class allocator;
19 template <> class allocator<void>;
21 // 20.4.1.2, allocator globals
22 template <class T, class U>
23 bool operator==(const allocator<T>&, const allocator<U>&) throw()
28 template <class T, class U>
29 bool operator!=(const allocator<T>&, const allocator<U>&) throw()
34 // 20.4.2, raw storage iterator:
35 // @@@ not defined, use the std one @@@
36 //template <class OutputIterator, class T> class raw_storage_iterator;
38 // 20.4.3, temporary buffers:
39 // @@@ not defined, use the std one @@@
41 //pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n);
42 // @@@ not defined, use the std one @@@
44 // void return_temporary_buffer(T* p);
46 // 20.4.4, specialized algorithms:
47 template <class InputIterator, class ForwardIterator>
49 uninitialized_copy(InputIterator first, InputIterator last,
50 ForwardIterator result);
52 template <class ForwardIterator, class Size, class T>
53 void uninitialized_fill_n(ForwardIterator first, Size n, const T &x);
55 // @@@ not defined, use the std one @@@
56 // template<class X> class auto_ptr;
61 template <class T> class allocator;
62 // specialize for void:
63 template <> class allocator<void>
66 typedef void *pointer;
67 typedef const void *const_pointer;
68 // reference-to-void members are impossible.
69 typedef void value_type;
70 template <class U> struct rebind
72 typedef allocator<U> other;
76 template <class T> class allocator
79 typedef size_t size_type;
80 typedef std::ptrdiff_t difference_type;
82 typedef const T *const_pointer;
84 typedef const T &const_reference;
87 template <class U> struct rebind
89 typedef allocator<U> other;
91 allocator() throw() {}
92 allocator(const allocator &) throw() {}
93 template <class U> allocator(const allocator<U>&) throw() {}
94 ~allocator() throw() {}
95 pointer address(reference x) const
99 const_pointer address(const_reference x)
103 pointer allocate(size_type n, allocator<void>::const_pointer = 0)
105 return static_cast<pointer>(::operator new(n * sizeof(T)));
107 void deallocate(pointer p, size_type)
109 ::operator delete(p);
111 size_type max_size() const throw()
113 return size_type(-1);
115 void construct(pointer p, const T &val)
117 new((void *) p) T(val);
119 void destroy(pointer p)
128 template <class T> class mallocator
131 typedef size_t size_type;
132 typedef ptrdiff_t difference_type;
134 typedef const T *const_pointer;
135 typedef T &reference;
136 typedef const T &const_reference;
137 typedef T value_type;
139 template <class U> struct rebind
141 typedef mallocator<U> other;
143 mallocator() throw() {}
144 mallocator(const mallocator &) throw() {}
145 template <class U> mallocator(const mallocator<U>&) throw() {}
146 ~mallocator() throw() {}
147 pointer address(reference x) const
151 const_pointer address(const_reference x)
155 pointer allocate(size_type n, yasli::allocator<void>::const_pointer = 0)
157 return static_cast<pointer>(malloc(n * sizeof(T)));
159 void deallocate(pointer p, size_type)
163 size_type max_size() const throw()
165 return size_type(-1);
167 void construct(pointer p, const T &val)
169 new((void *) p) T(val);
171 void destroy(pointer p)
177 //--------------destroy--------
183 template <class A, class T>
184 static void destroy(A &a, T *p, typename A::size_type n) {}
186 template <class ForwardIterator>
187 static void destroy_range(ForwardIterator b, ForwardIterator e) {}
192 template <class A, class T>
193 static void destroy(A &a, T *p, typename A::size_type n)
195 const typename A::pointer p1 = p + n;
196 for (; p < p1; ++p) a.destroy(p);
199 template <class ForwardIterator>
200 static void destroy_range(ForwardIterator b, ForwardIterator e)
202 typedef typename std::iterator_traits<ForwardIterator>::value_type
204 for (; b != e; ++b) (*b).~value_type();
209 template <class A, class T>
210 void destroy(A &a, T *p, typename A::size_type n)
212 yasli_nstd::type_selector<yasli_nstd::is_class<T>::value != 0,
215 >::result::destroy(a, p, n);
218 template <class ForwardIterator>
219 void destroy_range(ForwardIterator b, ForwardIterator e)
221 yasli_nstd::type_selector<
222 yasli_nstd::is_class<typename std::iterator_traits<ForwardIterator>
223 ::value_type>::value != 0,
226 >::result::destroy_range(b, e);
232 template <class It1, class It2>
233 It2 uninitialized_move(It1 b, It1 e, It2 d)
235 return mojo::uninitialized_move(b, e, d);
239 struct generic_allocator_traits
241 static typename A::pointer
244 typename A::pointer b,
245 typename A::pointer e,
246 typename A::size_type newSize)
248 typename A::pointer p1 = a.allocate(newSize, b);
249 const typename A::size_type oldSize = e - b;
250 if (oldSize <= newSize) // expand
252 yasli_protocols::move_traits<typename A::value_type>::destructive_move(
257 yasli_protocols::move_traits<typename A::value_type>::destructive_move(
259 yasli_nstd::destroy(a, b + newSize, oldSize - newSize);
261 a.deallocate(b, oldSize);
265 static bool reallocate_inplace(
267 typename A::pointer b,
268 typename A::size_type newSize)
274 generic_allocator_traits();
278 struct allocator_traits : public generic_allocator_traits<A>
283 struct allocator_traits< yasli::allocator<T> >
284 : public generic_allocator_traits< yasli::allocator<T> >
286 #if YASLI_NEW_IS_MALLOC != 0
288 static bool reallocate_inplace(
290 typename A::pointer b,
291 typename A::size_type newSize)
293 allocator_traits< yasli_nstd::mallocator<T> >
294 ::reallocate_inplace(a, b, newSize);
297 static typename yasli::allocator<T>::pointer
299 yasli::allocator<T>& a,
300 typename yasli::allocator<T>::pointer b,
301 typename yasli::allocator<T>::pointer e,
302 typename yasli::allocator<T>::size_type newSize)
304 allocator_traits< yasli_nstd::mallocator<T> >
305 ::reallocate(a, b, e, newSize);
307 #endif//yasli_new_is_malloc
311 struct allocator_traits< yasli_nstd::mallocator<T> >
312 : public generic_allocator_traits< yasli_nstd::mallocator<T> >
314 #if YASLI_HAS_EXPAND && YASLI_HAS_EFFICIENT_MSIZE
315 static bool reallocate_inplace(
316 yasli_nstd::mallocator<T>& a,
317 typename yasli_nstd::mallocator<T>::pointer b,
318 typename yasli_nstd::mallocator<T>::size_type newSize)
320 if (b == 0) return malloc(newSize);
326 return b == yasli_platform::expand(b, newSize)
327 && yasli_platform::msize(b) >= newSize;
330 static typename yasli_nstd::mallocator<T>::pointer
332 yasli_nstd::mallocator<T>& a,
333 typename yasli_nstd::mallocator<T>::pointer b,
334 typename yasli_nstd::mallocator<T>::pointer e,
335 typename yasli_nstd::mallocator<T>::size_type newSize)
337 if (yasli_nstd::is_memmoveable<T>::value)
339 return static_cast<T *>(realloc(b, newSize));
341 if(reallocate_inplace(a, b, newSize)) return b;
342 return generic_allocator_traits< yasli_nstd::mallocator<T> >::
343 reallocate(a, b, e, newSize);
350 //Here is where type_selector is really much more ugly than
353 //----------------UNINIT COPY--------
357 template <class InputItr, class FwdItr>
358 struct uninitialized_safe_copier
360 static FwdItr execute(InputItr first, InputItr last, FwdItr result)
369 if (!current) return;
370 FwdItr end = *current;
371 typedef typename std::iterator_traits<FwdItr>::value_type T;
372 for (; begin != end; ++begin) (&*begin)->~T();
374 } guard = { result, &result };
375 for (; first != last; ++first, ++result)
376 new(&*result) typename std::iterator_traits<FwdItr>::value_type(*first);
383 struct uninitialized_memcopier
385 static T *execute(const T *first, const T *last, T *result)
387 yasli_nstd::is_memcopyable<T>::value;
388 const size_t s = last - first;
389 memmove(result, first, s * sizeof(T));
396 // @@@ TODO: specialize for yasli_nstd::fill_iterator
398 template <class InputItr, class FwdItr>
399 FwdItr uninitialized_copy(InputItr first, InputItr last, FwdItr result)
401 std::cout<<"neither\n";
402 return _impl::uninitialized_safe_copier<InputItr, FwdItr>::execute(first, last, result);
406 T *uninitialized_copy(const T *first, const T *last, T *result)
408 std::cout<<"const\n";
409 return yasli_nstd::type_selector<yasli_nstd::is_memcopyable<T>::value != 0,
410 _impl::uninitialized_memcopier<T>,
411 _impl::uninitialized_safe_copier<const T *, T *>
412 >::result::execute(first, last, result);
416 T *uninitialized_copy(T *first, T *last, T *result)
418 std::cout<<"non-const\n";
419 return uninitialized_copy(static_cast<const T *>(first),
420 static_cast<const T *>(last), result);
423 //-------------------------UNINIT FILL------
425 template <class ForwardIterator, class T>
427 uninitialized_fill(ForwardIterator first, ForwardIterator last,
432 ForwardIterator first;
433 ForwardIterator *pCrt;
436 if (pCrt) yasli_nstd::destroy_range(first, *pCrt);
438 } guard = { first, &first };
439 for (; first != last; ++first)
445 template <class T, class U>
447 uninitialized_fill(T *first, T *last, const U &x)
455 if (pCrt) yasli_nstd::destroy_range(first, *pCrt);
457 } guard = { first, &first };
458 assert(first <= last);
459 switch ((last - first) & 7u)
462 while (first != last)
487 assert(first <= last);
496 #endif // YASLI_MEMORY_H_