File indexing completed on 2024-03-24 16:06:00
0001 /* 0002 This file is part of kdev-pg 0003 Copyright 2005, 2006 Roberto Raggi <roberto@kdevelop.org> 0004 0005 Permission to use, copy, modify, distribute, and sell this software and its 0006 documentation for any purpose is hereby granted without fee, provided that 0007 the above copyright notice appear in all copies and that both that 0008 copyright notice and this permission notice appear in supporting 0009 documentation. 0010 0011 The above copyright notice and this permission notice shall be included in 0012 all copies or substantial portions of the Software. 0013 0014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0017 KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 0018 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 0019 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0020 */ 0021 0022 #ifndef KDEV_PG_ALLOCATOR_H 0023 #define KDEV_PG_ALLOCATOR_H 0024 0025 #include <memory> 0026 #include <cstdlib> 0027 #include <cstring> 0028 0029 #include <QtGlobal> 0030 0031 namespace KDevPG 0032 { 0033 0034 template <class _Tp> 0035 class Allocator 0036 { 0037 public: 0038 typedef _Tp valueType; 0039 typedef _Tp* pointer; 0040 typedef const _Tp* constPointer; 0041 typedef _Tp& reference; 0042 typedef const _Tp& constReference; 0043 typedef ::std::size_t sizeType; 0044 typedef qint64 differenceType; 0045 0046 static const sizeType maxBlockCount = sizeType( -1); 0047 0048 Allocator() 0049 { 0050 sBlockIndex = sizeType(-1); 0051 sCurrentIndex = 0; 0052 sStorage = nullptr; 0053 sCurrentBlock = nullptr; 0054 } 0055 0056 ~Allocator() 0057 { 0058 if (sStorage != nullptr) 0059 { 0060 for (sizeType index = 0; index <= sBlockIndex; ++index) 0061 delete[] sStorage[index]; 0062 std::free(sStorage); 0063 } 0064 } 0065 0066 bool contains(void* ptr) 0067 { 0068 for(sizeType i = 0; i <= sBlockIndex; ++i) 0069 if(ptr >= (void*)(sStorage[i]) && ptr < (void*)(sStorage[i] + sBlockSize)) 0070 return true; 0071 return false; 0072 } 0073 0074 pointer address(reference __val) 0075 { 0076 return &__val; 0077 } 0078 constPointer address(constReference __val) const 0079 { 0080 return &__val; 0081 } 0082 0083 pointer allocate(sizeType __n, const void* = nullptr) 0084 { 0085 const sizeType bytes = __n * sizeof(_Tp); 0086 0087 if (sCurrentBlock == nullptr 0088 || sBlockSize < sCurrentIndex + bytes) 0089 { 0090 ++sBlockIndex; 0091 0092 sStorage = reinterpret_cast<char**> 0093 (std::realloc(sStorage, sizeof(char*) * (1 + sBlockIndex))); 0094 0095 sCurrentBlock = sStorage[sBlockIndex] = reinterpret_cast<char*> 0096 (new char[sBlockSize]); 0097 0098 std::memset(sCurrentBlock, 0, sBlockSize); 0099 sCurrentIndex = 0; 0100 } 0101 0102 pointer p = reinterpret_cast<pointer> 0103 (sCurrentBlock + sCurrentIndex); 0104 0105 sCurrentIndex += bytes; 0106 0107 return p; 0108 } 0109 0110 void deallocate(pointer /*__p*/, sizeType /*__n*/) 0111 {} 0112 0113 sizeType maxSize() const 0114 { 0115 return sizeType( -1) / sizeof(_Tp); 0116 } 0117 0118 void contruct(pointer __p, constReference __val) 0119 { 0120 new (__p) _Tp(__val); 0121 } 0122 void destruct(pointer __p) 0123 { 0124 __p->~_Tp(); 0125 } 0126 0127 private: 0128 template <class _Tp1> 0129 class Rebind 0130 { 0131 typedef Allocator<_Tp1> other; 0132 }; 0133 0134 template <class _Tp1> 0135 Allocator(const Allocator<_Tp1> &/*__o*/) 0136 {} 0137 0138 private: 0139 static const sizeType sBlockSize; 0140 sizeType sBlockIndex; 0141 sizeType sCurrentIndex; 0142 char *sCurrentBlock; 0143 char **sStorage; 0144 }; 0145 0146 template <class _Tp> 0147 const typename Allocator<_Tp>::sizeType 0148 Allocator<_Tp>::sBlockSize = 1 << 16; // 64K 0149 0150 } 0151 0152 #endif // KDEV_PG_ALLOCATOR_H