$search
00001 /********************************************************************* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2010, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of the Willow Garage nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 *********************************************************************/ 00034 00035 #ifndef ALLOCATORS_ALIGNED_H 00036 #define ALLOCATORS_ALIGNED_H 00037 00038 #include <cstdlib> 00039 #include <boost/cstdint.hpp> 00040 00041 namespace allocators 00042 { 00043 00044 // alignedMalloc/alignedFree implementations found at 00045 // http://www.gamasutra.com/view/feature/3942/data_alignment_part_1.php?page=2 00046 00053 inline void* alignedMalloc(size_t size, size_t alignment) 00054 { 00055 const int pointerSize = sizeof(void*); 00056 const int requestedSize = size + alignment - 1 + pointerSize; 00057 void* raw = std::malloc(requestedSize); 00058 00059 if (!raw) 00060 { 00061 return 0; 00062 } 00063 00064 void* start = (uint8_t*)raw + pointerSize; 00065 void* aligned = (void*)(((uintptr_t)((uint8_t*)start+alignment-1)) & ~(alignment-1)); 00066 *(void**)((uint8_t*)aligned-pointerSize) = raw; 00067 return aligned; 00068 } 00069 00074 inline void alignedFree(void* aligned) 00075 { 00076 if (!aligned) 00077 { 00078 return; 00079 } 00080 00081 void* raw = *(void**)((uint8_t*)aligned - sizeof(void*)); 00082 std::free(raw); 00083 } 00084 00085 template<class T, size_t align> class AlignedAllocator; 00086 00087 // specialize for void: 00088 template<size_t align> 00089 class AlignedAllocator<void, align> 00090 { 00091 public: 00092 typedef void* pointer; 00093 typedef const void* const_pointer; 00094 // reference to void members are impossible. 00095 typedef void value_type; 00096 00097 template<class U> 00098 struct rebind 00099 { 00100 typedef AlignedAllocator<U, align> other; 00101 }; 00102 }; 00103 00109 template<class T, size_t align> 00110 class AlignedAllocator 00111 { 00112 public: 00113 typedef size_t size_type; 00114 typedef ptrdiff_t difference_type; 00115 typedef T* pointer; 00116 typedef const T* const_pointer; 00117 typedef T& reference; 00118 typedef const T& const_reference; 00119 typedef T value_type; 00120 00121 template<class U> 00122 struct rebind 00123 { 00124 typedef AlignedAllocator<U, align> other; 00125 }; 00126 00127 AlignedAllocator() throw () 00128 { 00129 } 00130 00131 ~AlignedAllocator() throw () 00132 { 00133 } 00134 00135 pointer address(reference r) const 00136 { 00137 return &r; 00138 } 00139 const_pointer address(const_reference r) const 00140 { 00141 return &r; 00142 } 00143 size_type max_size() const throw () 00144 { 00145 return ~size_type(0); 00146 } 00147 pointer allocate(size_type n, typename AlignedAllocator<void, align>::const_pointer hint = 0) 00148 { 00149 void* mem = alignedMalloc(n * sizeof(T), align); 00150 if (!mem) 00151 { 00152 throw std::bad_alloc(); 00153 } 00154 00155 return static_cast<pointer>(mem); 00156 } 00157 void deallocate(pointer p, size_type n) 00158 { 00159 alignedFree(p); 00160 } 00161 00162 void construct(pointer p, const_reference val) 00163 { 00164 new (p) T(val); 00165 } 00166 void destroy(pointer p) 00167 { 00168 p->~T(); 00169 } 00170 }; 00171 00172 } // namespace allocators 00173 00174 #endif // ALLOCATORS_ALIGNED_H 00175