📄 yasli_memory.h
字号:
#ifndef YASLI_MEMORY_H_#define YASLI_MEMORY_H_// $Id: yasli_memory.h 754 2006-10-17 19:59:11Z syntheticpp $#include "yasli_traits.h"#include "yasli_protocols.h"//!#include <cassert>#include <cstddef>#include <misc/mojo.h>//NOT A SAFE WAY TO INCLUDE ITnamespace yasli { // 20.4.1, the default allocator: template <class T> class allocator; template <> class allocator<void>; // 20.4.1.2, allocator globals template <class T, class U> bool operator==(const allocator<T>&, const allocator<U>&) throw() { return true; } template <class T, class U> bool operator!=(const allocator<T>&, const allocator<U>&) throw() { return false; } // 20.4.2, raw storage iterator: // @@@ not defined, use the std one @@@ //template <class OutputIterator, class T> class raw_storage_iterator; // 20.4.3, temporary buffers: // @@@ not defined, use the std one @@@ //template <class T> //pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n); // @@@ not defined, use the std one @@@ // template <class T> // void return_temporary_buffer(T* p); // 20.4.4, specialized algorithms: template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); template <class ForwardIterator, class Size, class T> void uninitialized_fill_n(ForwardIterator first, Size n, const T& x); // 20.4.5, pointers: // @@@ not defined, use the std one @@@ // template<class X> class auto_ptr;}namespace yasli { template <class T> class allocator; // specialize for void: template <> class allocator<void> { public: typedef void* pointer; typedef const void* const_pointer; // reference-to-void members are impossible. typedef void value_type; template <class U> struct rebind { typedef allocator<U> other; }; }; template <class T> class allocator { public: typedef size_t size_type; typedef std::ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; template <class U> struct rebind { typedef allocator<U> other; }; allocator() throw() {} allocator(const allocator&) throw() {} template <class U> allocator(const allocator<U>&) throw() {} ~allocator() throw() {} pointer address(reference x) const { return &x; } const_pointer address(const_reference x) { return &x; } pointer allocate(size_type n, allocator<void>::const_pointer = 0) { return static_cast<pointer>(::operator new(n * sizeof(T))); } void deallocate(pointer p, size_type) { ::operator delete(p); } size_type max_size() const throw() { return size_type(-1); } void construct(pointer p, const T& val) { new((void *) p) T(val); } void destroy(pointer p) { ((T*) p)->~T(); } };} // namespace yaslinamespace yasli_nstd{ template <class T> class mallocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; template <class U> struct rebind { typedef mallocator<U> other; }; mallocator() throw() {} mallocator(const mallocator&) throw() {} template <class U> mallocator(const mallocator<U>&) throw() {} ~mallocator() throw() {} pointer address(reference x) const { return &x; } const_pointer address(const_reference x) { return &x; } pointer allocate(size_type n, yasli::allocator<void>::const_pointer = 0) { return static_cast<pointer>(malloc(n * sizeof(T))); } void deallocate(pointer p, size_type) { free(p); } size_type max_size() const throw() { return size_type(-1); } void construct(pointer p, const T& val) { new((void *) p) T(val); } void destroy(pointer p) { ((T*) p)->~T(); } }; //--------------destroy-------- namespace _impl { struct non_destroyer { template <class A, class T> static void destroy(A& a, T* p, typename A::size_type n) {} template <class ForwardIterator> static void destroy_range(ForwardIterator b, ForwardIterator e) {} }; struct destroyer { template <class A, class T> static void destroy(A& a, T* p, typename A::size_type n) { const typename A::pointer p1 = p + n; for (; p < p1; ++p) a.destroy(p); } template <class ForwardIterator> static void destroy_range(ForwardIterator b, ForwardIterator e) { typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; for (; b != e; ++b) (*b).~value_type(); } }; } template <class A, class T> void destroy(A& a, T* p, typename A::size_type n) { yasli_nstd::type_selector<yasli_nstd::is_class<T>::value != 0, _impl::destroyer, _impl::non_destroyer >::result::destroy(a, p, n); } template <class ForwardIterator> void destroy_range(ForwardIterator b, ForwardIterator e) { yasli_nstd::type_selector< yasli_nstd::is_class<typename std::iterator_traits<ForwardIterator> ::value_type>::value != 0, _impl::destroyer, _impl::non_destroyer >::result::destroy_range(b, e); } //--------------- template <class It1, class It2> It2 uninitialized_move(It1 b, It1 e, It2 d) { return mojo::uninitialized_move(b, e, d); } template <class A> struct generic_allocator_traits { static typename A::pointer reallocate( A& a, typename A::pointer b, typename A::pointer e, typename A::size_type newSize) { typename A::pointer p1 = a.allocate(newSize, b); const typename A::size_type oldSize = e - b; if (oldSize <= newSize) // expand { yasli_protocols::move_traits<typename A::value_type>::destructive_move( b, b + oldSize, p1); } else // shrink { yasli_protocols::move_traits<typename A::value_type>::destructive_move( b, b + newSize, p1); yasli_nstd::destroy(a, b + newSize, oldSize - newSize); } a.deallocate(b, oldSize); return p1; } static bool reallocate_inplace( A& a, typename A::pointer b, typename A::size_type newSize) { return false; } private: generic_allocator_traits(); }; template <class A> struct allocator_traits : public generic_allocator_traits<A> { }; template <class T> struct allocator_traits< yasli::allocator<T> > : public generic_allocator_traits< yasli::allocator<T> > {#if YASLI_NEW_IS_MALLOC != 0 static bool reallocate_inplace( A& a, typename A::pointer b, typename A::size_type newSize) { allocator_traits< yasli_nstd::mallocator<T> > ::reallocate_inplace(a, b, newSize); } static typename yasli::allocator<T>::pointer reallocate( yasli::allocator<T>& a, typename yasli::allocator<T>::pointer b, typename yasli::allocator<T>::pointer e, typename yasli::allocator<T>::size_type newSize) { allocator_traits< yasli_nstd::mallocator<T> > ::reallocate(a, b, e, newSize); }#endif//yasli_new_is_malloc }; template <class T> struct allocator_traits< yasli_nstd::mallocator<T> > : public generic_allocator_traits< yasli_nstd::mallocator<T> > {#if YASLI_HAS_EXPAND && YASLI_HAS_EFFICIENT_MSIZE static bool reallocate_inplace( yasli_nstd::mallocator<T>& a, typename yasli_nstd::mallocator<T>::pointer b, typename yasli_nstd::mallocator<T>::size_type newSize) { if (b == 0) return malloc(newSize); if (newSize == 0) {free(b); return false;} return b == yasli_platform::expand(b, newSize) && yasli_platform::msize(b) >= newSize; } #endif static typename yasli_nstd::mallocator<T>::pointer reallocate( yasli_nstd::mallocator<T>& a, typename yasli_nstd::mallocator<T>::pointer b, typename yasli_nstd::mallocator<T>::pointer e, typename yasli_nstd::mallocator<T>::size_type newSize) { if (yasli_nstd::is_memmoveable<T>::value) { return static_cast<T*>(realloc(b, newSize)); } if(reallocate_inplace(a, b, newSize)) return b; return generic_allocator_traits< yasli_nstd::mallocator<T> >:: reallocate(a, b, e, newSize); } };}namespace yasli{ //Here is where type_selector is really much more ugly than //enable_if. //----------------UNINIT COPY-------- namespace _impl { //safe template <class InputItr, class FwdItr> struct uninitialized_safe_copier { static FwdItr execute(InputItr first, InputItr last, FwdItr result) { // struct ScopeGuard { FwdItr begin; FwdItr* current; ~ScopeGuard() { if (!current) return; FwdItr end = *current; typedef typename std::iterator_traits<FwdItr>::value_type T; for (; begin != end; ++begin) (&*begin)->~T(); } } guard = { result, &result }; for (; first != last; ++first, ++result) new(&*result) typename std::iterator_traits<FwdItr>::value_type(*first); // commit return result; } }; template <class T> struct uninitialized_memcopier { static T* execute(const T* first, const T* last, T* result) { yasli_nstd::is_memcopyable<T>::value; const size_t s = last - first; memmove(result, first, s * sizeof(T)); return result + s; } }; }// _impl // @@@ TODO: specialize for yasli_nstd::fill_iterator template <class InputItr, class FwdItr> FwdItr uninitialized_copy(InputItr first, InputItr last, FwdItr result) { std::cout<<"neither\n"; return _impl::uninitialized_safe_copier<InputItr, FwdItr>::execute(first, last, result); } template <class T> T* uninitialized_copy(const T* first, const T* last, T* result) { std::cout<<"const\n"; return yasli_nstd::type_selector<yasli_nstd::is_memcopyable<T>::value != 0, _impl::uninitialized_memcopier<T>, _impl::uninitialized_safe_copier<const T*, T*> >::result::execute(first, last, result); } template <class T> T* uninitialized_copy(T* first, T* last, T* result) { std::cout<<"non-const\n"; return uninitialized_copy(static_cast<const T*>(first), static_cast<const T*>(last), result); } //-------------------------UNINIT FILL------ template <class ForwardIterator, class T> void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x) { struct ScopeGuard { ForwardIterator first; ForwardIterator* pCrt; ~ScopeGuard() { if (pCrt) yasli_nstd::destroy_range(first, *pCrt); } } guard = { first, &first }; for (; first != last; ++first) new(&*first) T(x); // Commit guard.pCrt = 0; } template <class T, class U> void uninitialized_fill(T* first, T* last, const U& x) { struct ScopeGuard { T* first; T** pCrt; ~ScopeGuard() { if (pCrt) yasli_nstd::destroy_range(first, *pCrt); } } guard = { first, &first }; assert(first <= last); switch ((last - first) & 7u) { case 0: while (first != last) { new(first) T(x); ++first; case 7: new(first) T(x); ++first; case 6: new(first) T(x); ++first; case 5: new(first) T(x); ++first; case 4: new(first) T(x); ++first; case 3: new(first) T(x); ++first; case 2: new(first) T(x); ++first; case 1: new(first) T(x); ++first; assert(first <= last); } } // Commit guard.pCrt = 0; } }// yasli#endif // YASLI_MEMORY_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -