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
10f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#ifndef TEST_ALLOCATOR_H
11f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#define TEST_ALLOCATOR_H
12f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
13f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#include <cstddef>
14f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#include <type_traits>
154dc5b2198d1aa4ab585a3d4a87ee9626d681f9f7Dan Albert#include <utility>
16f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#include <cstdlib>
17f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#include <new>
18f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#include <climits>
19f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
20f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantclass test_alloc_base
21f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant{
22f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantpublic:
23f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    static int count;
24f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantpublic:
25f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    static int throw_after;
26f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant};
27f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
28f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantint test_alloc_base::count = 0;
29f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantint test_alloc_base::throw_after = INT_MAX;
30f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
31f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnanttemplate <class T>
32f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantclass test_allocator
33f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    : public test_alloc_base
34f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant{
35f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    int data_;
36f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
37f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> friend class test_allocator;
38f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantpublic:
39f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
40f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef unsigned                                                   size_type;
41f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef int                                                        difference_type;
42f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef T                                                          value_type;
43f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef value_type*                                                pointer;
44f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef const value_type*                                          const_pointer;
45f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef typename std::add_lvalue_reference<value_type>::type       reference;
46f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
47f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
48f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> struct rebind {typedef test_allocator<U> other;};
49f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
50f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    test_allocator() throw() : data_(-1) {}
51f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    explicit test_allocator(int i) throw() : data_(i) {}
52f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    test_allocator(const test_allocator& a) throw()
53f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        : data_(a.data_) {}
54f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> test_allocator(const test_allocator<U>& a) throw()
55f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        : data_(a.data_) {}
56f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    ~test_allocator() throw() {data_ = 0;}
57f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    pointer address(reference x) const {return &x;}
58f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    const_pointer address(const_reference x) const {return &x;}
59f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    pointer allocate(size_type n, const void* = 0)
60f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {
619976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant            if (count >= throw_after) {
629976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
63f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant                throw std::bad_alloc();
649976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant#else
659976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant                std::terminate();
669976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant#endif
679976b5511a5ff7c67dc7bc024604efa0baf43625Howard Hinnant            }
68f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant            ++count;
69f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant            return (pointer)std::malloc(n * sizeof(T));
70f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        }
71f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    void deallocate(pointer p, size_type n)
72f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {--count; std::free(p);}
73f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    size_type max_size() const throw()
74f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return UINT_MAX / sizeof(T);}
75f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    void construct(pointer p, const T& val)
76f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {::new(p) T(val);}
7773d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
78f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    void construct(pointer p, T&& val)
79f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {::new(p) T(std::move(val));}
8073d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
81f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    void destroy(pointer p) {p->~T();}
82f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
83f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    friend bool operator==(const test_allocator& x, const test_allocator& y)
84f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return x.data_ == y.data_;}
85f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    friend bool operator!=(const test_allocator& x, const test_allocator& y)
86f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return !(x == y);}
87f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant};
88f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
89f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnanttemplate <>
90f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantclass test_allocator<void>
91f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    : public test_alloc_base
92f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant{
93f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    int data_;
94f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
95f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> friend class test_allocator;
96f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantpublic:
97f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
98f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef unsigned                                                   size_type;
99f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef int                                                        difference_type;
100f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef void                                                       value_type;
101f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef value_type*                                                pointer;
102f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef const value_type*                                          const_pointer;
103f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
104f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> struct rebind {typedef test_allocator<U> other;};
105f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
106f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    test_allocator() throw() : data_(-1) {}
107f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    explicit test_allocator(int i) throw() : data_(i) {}
108f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    test_allocator(const test_allocator& a) throw()
109f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        : data_(a.data_) {}
110f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> test_allocator(const test_allocator<U>& a) throw()
111f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        : data_(a.data_) {}
112f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    ~test_allocator() throw() {data_ = 0;}
113f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
114f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    friend bool operator==(const test_allocator& x, const test_allocator& y)
115f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return x.data_ == y.data_;}
116f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    friend bool operator!=(const test_allocator& x, const test_allocator& y)
117f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return !(x == y);}
118f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant};
119f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
120f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnanttemplate <class T>
121f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantclass other_allocator
122f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant{
123f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    int data_;
124f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
125f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> friend class other_allocator;
126f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
127f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnantpublic:
128f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef T value_type;
129f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
130f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    other_allocator() : data_(-1) {}
131f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    explicit other_allocator(int i) : data_(i) {}
132f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    template <class U> other_allocator(const other_allocator<U>& a)
133f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        : data_(a.data_) {}
134f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    T* allocate(std::size_t n)
135f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return (T*)std::malloc(n * sizeof(T));}
136f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    void deallocate(T* p, std::size_t n)
137f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {std::free(p);}
138f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
139f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    other_allocator select_on_container_copy_construction() const
140f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return other_allocator(-2);}
141f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
142f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    friend bool operator==(const other_allocator& x, const other_allocator& y)
143f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return x.data_ == y.data_;}
144f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    friend bool operator!=(const other_allocator& x, const other_allocator& y)
145f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return !(x == y);}
146f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
147f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef std::true_type propagate_on_container_copy_assignment;
148f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef std::true_type propagate_on_container_move_assignment;
149f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    typedef std::true_type propagate_on_container_swap;
150f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
151f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
152f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant    std::size_t max_size() const
153f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant        {return UINT_MAX / sizeof(T);}
154f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
155f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
156f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant};
157f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant
158f39daa8e5a5f7d7eb19f391497a29b4fa0eec28dHoward Hinnant#endif  // TEST_ALLOCATOR_H
159