198760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow//===----------------------------------------------------------------------===//
298760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow//
398760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow//                     The LLVM Compiler Infrastructure
498760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow//
598760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow// This file is dual licensed under the MIT and the University of Illinois Open
698760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow// Source Licenses. See LICENSE.TXT for details.
798760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow//
898760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow//===----------------------------------------------------------------------===//
998760c18f85bafd98dde7a309e1b0e677abd47d8Marshall Clow
10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#ifndef STACK_ALLOCATOR_H
11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#define STACK_ALLOCATOR_H
12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <cstddef>
14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <new>
15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class T, std::size_t N>
17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass stack_allocator
18bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    char buf_[sizeof(T)*N];
20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    char* ptr_;
21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef T                 value_type;
23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef value_type*       pointer;
24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef const value_type* const_pointer;
25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef value_type&       reference;
26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef const value_type& const_reference;
27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef std::size_t       size_type;
28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    typedef std::ptrdiff_t    difference_type;
29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    template <class U> struct rebind {typedef stack_allocator<U, N> other;};
31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    stack_allocator() : ptr_(buf_) {}
33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantprivate:
35bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    stack_allocator(const stack_allocator&);// = delete;
36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    stack_allocator& operator=(const stack_allocator&);// = delete;
37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic:
39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    pointer allocate(size_type n, const void* = 0)
40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
419976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant        if (n > N - (ptr_ - buf_) / sizeof(value_type)) {
429976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
43bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            throw std::bad_alloc();
449976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant#else
459976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant            std::terminate();
469976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant#endif
479976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant        }
48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        pointer r = (T*)ptr_;
49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        ptr_ += n * sizeof(T);
50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return r;
51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    void deallocate(pointer p, size_type n)
53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        if ((char*)(p + n) == ptr_)
55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            ptr_ = (char*)p;
56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    size_type max_size() const {return N;}
59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant};
60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
61bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttemplate <class T, std::size_t N>
62bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantinline
63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
64bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantswap(stack_allocator<T, N>& x, stack_allocator<T, N>& y) {}
65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
666046aced820aaab4f14f2026531dd11d10690691Howard Hinnant#endif  // STACK_ALLOCATOR_H
67