qpid/InlineAllocator.h Source File

Apache Qpid - AMQP Messaging for Java JMS, C++, Python, Ruby, and .NET | Apache Qpid Documentation

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

qpid/InlineAllocator.h
Go to the documentation of this file.

    00001 #ifndef QPID_INLINEALLOCATOR_H
    00002 #define QPID_INLINEALLOCATOR_H
    00003
    00004 /*
    00005  *
    00006  * Licensed to the Apache Software Foundation (ASF) under one
    00007  * or more contributor license agreements.  See the NOTICE file
    00008  * distributed with this work for additional information
    00009  * regarding copyright ownership.  The ASF licenses this file
    00010  * to you under the Apache License, Version 2.0 (the
    00011  * "License"); you may not use this file except in compliance
    00012  * with the License.  You may obtain a copy of the License at
    00013  *
    00014  *   http://www.apache.org/licenses/LICENSE-2.0
    00015  *
    00016  * Unless required by applicable law or agreed to in writing,
    00017  * software distributed under the License is distributed on an
    00018  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    00019  * KIND, either express or implied.  See the License for the
    00020  * specific language governing permissions and limitations
    00021  * under the License.
    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     // POD object with alignment and size to hold Max value_types.
    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 // Rebind: if RequestedType == InlineType, use the InlineAllocator,
    00087 // otherwise, use the BaseAllocator without any inlining.
    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 } // namespace qpid
    00100
    00101 #endif