#ifndef STD_ALLOC_H #define STD_ALLOC_H // ---------------------- Allocator for using STL ------------------------ #include "xmmintrin.h" #include #include namespace nsL1 { // #define DEBUG_nsL1 template class SimdAlloc { public: // type definitions typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // rebind allocator to type U template struct rebind { typedef SimdAlloc other; }; // return address of values pointer address (reference value) const { return &value; } const_pointer address (const_reference value) const { return &value; } /* constructors and destructor * - nothing to do because the allocator has no state */ SimdAlloc() throw() { } SimdAlloc(const SimdAlloc&) throw() { } template SimdAlloc (const SimdAlloc&) throw() { } ~SimdAlloc() throw() { } // return maximum number of elements that can be allocated size_type max_size () const throw() { return std::numeric_limits::max() / sizeof(T); } // allocate but don't initialize num elements of type T pointer allocate (size_type num, const void* = 0) { // print message and allocate memory with global new #ifdef DEBUG_nsL1 std::cerr << "Allocator: allocate " << num << " element(s)" << " of size " << sizeof(T) << std::endl; #endif // DEBUG_nsL1 pointer ret = reinterpret_cast( /*T::*/operator new(num*sizeof(T)) ); #ifdef DEBUG_nsL1 std::cerr << " allocated at: " << (void*)ret << std::endl; #endif // DEBUG_nsL1 return ret; } // initialize elements of allocated storage p with value value void construct (pointer p, const T& value) { // initialize memory with placement new #ifdef DEBUG_nsL1 std::cerr << "Allocator: construct " << p /*<< " " << value*/ << std::endl; #endif // DEBUG_nsL1 new(p) T(value); // p = reinterpret_cast( operator new(sizeof(T), p) ); // *p = value; #ifdef DEBUG_nsL1 std::cerr << "done." << std::endl; #endif // DEBUG_nsL1 } // destroy elements of initialized storage p void destroy (pointer p) { // destroy objects by calling their destructor #ifdef DEBUG_nsL1 std::cerr << "Allocator: destroy " << p << std::endl; #endif // DEBUG_nsL1 p->~T(); #ifdef DEBUG_nsL1 std::cerr << "done." << std::endl; #endif // DEBUG_nsL1 } // deallocate storage p of deleted elements void deallocate (pointer p, size_type num) { // print message and deallocate memory with global delete #ifdef DEBUG_nsL1 std::cerr << "Allocator: deallocate " << num << " element(s)" << " of size " << sizeof(T) << " at: " << static_cast(p) << std::endl; #endif // DEBUG_nsL1 /*T::*/operator delete(static_cast(p), num*sizeof(T)); #ifdef DEBUG_nsL1 std::cerr << "done." << std::endl; #endif // DEBUG_nsL1 } void *operator new(size_t size, void *ptr) { return ::operator new(size, ptr);} void *operator new[](size_t size, void *ptr) { return ::operator new(size, ptr);} void *operator new(size_t size) { return _mm_malloc(size, 16); } void *operator new[](size_t size) { return _mm_malloc(size, 16); } void operator delete(void *ptr, size_t) { _mm_free(ptr); } void operator delete[](void *ptr, size_t) { _mm_free(ptr); } }; // SimdAlloc // return that all specializations of this allocator are interchangeable template bool operator== (const SimdAlloc&, const SimdAlloc&) throw() { return true; } template bool operator!= (const SimdAlloc&, const SimdAlloc&) throw() { return false; } template struct vector { vector(){}; virtual ~vector(){}; typedef std::vector TStd; // typedef std::vector TSimd; typedef std::vector > TSimd; }; typedef nsL1::vector::TSimd vector_fvec; } // namespace nsL1 template struct nsL1vector: public nsL1::vector // just for use std::vector simultaniosly { }; #endif