00001 #ifndef QPID_INLINEALLOCATOR_H
00002 #define QPID_INLINEALLOCATOR_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <memory>
00026 #include <assert.h>
00027 #include <boost/type_traits/type_with_alignment.hpp>
00028 #include <boost/type_traits/alignment_of.hpp>
00029
00030 namespace qpid {
00031
00036 template <class BaseAllocator, size_t Max>
00037 class InlineAllocator : public BaseAllocator {
00038 public:
00039 typedef typename BaseAllocator::pointer pointer;
00040 typedef typename BaseAllocator::size_type size_type;
00041 typedef typename BaseAllocator::value_type value_type;
00042
00043 InlineAllocator() : allocated(false) {}
00044 InlineAllocator(const InlineAllocator& x) : BaseAllocator(x), allocated(false) {}
00045
00046 pointer allocate(size_type n) {
00047 if (n <= Max && !allocated) {
00048 allocated=true;
00049 return reinterpret_cast<value_type*>(address());
00050 }
00051 else
00052 return BaseAllocator::allocate(n, 0);
00053 }
00054
00055 void deallocate(pointer p, size_type n) {
00056 if (p == address()) {
00057 assert(allocated);
00058 allocated=false;
00059 }
00060 else
00061 BaseAllocator::deallocate(p, n);
00062 }
00063
00064 template<typename T1>
00065 struct rebind {
00066 typedef typename BaseAllocator::template rebind<T1>::other BaseOther;
00067 typedef InlineAllocator<BaseOther, Max> other;
00068 };
00069
00070 private:
00071
00072 static const size_t ALIGNMENT=boost::alignment_of<value_type>::value;
00073 typedef typename boost::type_with_alignment<ALIGNMENT>::type Aligner;
00074 union Store {
00075 Aligner aligner_;
00076 char sizer_[sizeof(value_type)*Max];
00077 } store;
00078 value_type* address() { return reinterpret_cast<value_type*>(&store); }
00079 bool allocated;
00080 };
00081
00082 }
00083
00084 #endif