File indexing completed on 2022-09-20 14:06:39

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