Go to the documentation of this file.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 
00032 template <typename RequestedType, typename InlineType, typename BaseAllocator, size_t Max>
00033 struct InlineRebind;
00034 
00035 
00040 template <class BaseAllocator, size_t Max>
00041 class InlineAllocator : public BaseAllocator {
00042   public:
00043     typedef typename BaseAllocator::pointer pointer;
00044     typedef typename BaseAllocator::size_type size_type;
00045     typedef typename BaseAllocator::value_type value_type;
00046 
00047     InlineAllocator() : allocated(false) {}
00048     InlineAllocator(const InlineAllocator& x) : BaseAllocator(x), allocated(false) {}
00049 
00050     pointer allocate(size_type n) {
00051         if (n <= Max && !allocated) {
00052             allocated=true;
00053             return reinterpret_cast<value_type*>(address());
00054         }
00055         else
00056             return BaseAllocator::allocate(n, 0);
00057     }
00058 
00059     void deallocate(pointer p, size_type n) {
00060         if (p == address()) {
00061             assert(allocated);
00062             allocated=false;
00063         }
00064         else
00065             BaseAllocator::deallocate(p, n);
00066     }
00067 
00068     template<typename T1>
00069     struct rebind {
00070         typedef typename InlineRebind<T1, value_type, BaseAllocator, Max>::other other;
00071     };
00072 
00073   private:
00074     
00075     static const size_t ALIGNMENT=boost::alignment_of<value_type>::value;
00076     typedef typename boost::type_with_alignment<ALIGNMENT>::type Aligner;
00077     union Store {
00078       Aligner aligner_;
00079       char sizer_[sizeof(value_type)*Max];
00080     } store;
00081     value_type* address() { return reinterpret_cast<value_type*>(&store); }
00082     bool allocated;
00083 };
00084 
00085 
00086 
00087 
00088 
00089 template <typename RequestedType, typename InlineType, typename BaseAllocator, size_t Max>
00090 struct InlineRebind {
00091     typedef typename BaseAllocator::template rebind<RequestedType>::other other;
00092 };
00093 
00094 template <typename T, typename BaseAllocator, size_t Max>
00095 struct InlineRebind<T, T, BaseAllocator, Max> {
00096     typedef typename qpid::InlineAllocator<BaseAllocator, Max> other;
00097 };
00098 
00099 } 
00100 
00101 #endif