blob: ca3b937c013846a8016969daf01cadc1c79ad47c [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___SSO_ALLOCATOR
12#define _LIBCPP___SSO_ALLOCATOR
13
14#include <__config>
15#include <type_traits>
16#include <new>
17
Saleem Abdulrasoolf1b30c42015-02-13 22:15:32 +000018#include <__undef___deallocate>
19
Howard Hinnant08e17472011-10-17 20:05:10 +000020#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000021#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000022#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000023
24_LIBCPP_BEGIN_NAMESPACE_STD
25
Howard Hinnant99968442011-11-29 18:15:50 +000026template <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000027
Howard Hinnant99968442011-11-29 18:15:50 +000028template <size_t _Np>
29class _LIBCPP_HIDDEN __sso_allocator<void, _Np>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000030{
31public:
32 typedef const void* const_pointer;
33 typedef void value_type;
34};
35
Howard Hinnant99968442011-11-29 18:15:50 +000036template <class _Tp, size_t _Np>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000037class _LIBCPP_HIDDEN __sso_allocator
38{
Howard Hinnant99968442011-11-29 18:15:50 +000039 typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000040 bool __allocated_;
41public:
42 typedef size_t size_type;
43 typedef _Tp* pointer;
44 typedef _Tp value_type;
45
46 _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
47 _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
Howard Hinnant99968442011-11-29 18:15:50 +000048 template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000049 : __allocated_(false) {}
50private:
51 __sso_allocator& operator=(const __sso_allocator&);
52public:
Howard Hinnant99968442011-11-29 18:15:50 +000053 _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = 0)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000054 {
Howard Hinnant99968442011-11-29 18:15:50 +000055 if (!__allocated_ && __n <= _Np)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000056 {
57 __allocated_ = true;
58 return (pointer)&buf_;
59 }
Richard Smith73c1fce2014-06-04 19:54:15 +000060 return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000061 }
62 _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type)
63 {
64 if (__p == (pointer)&buf_)
65 __allocated_ = false;
66 else
Richard Smith73c1fce2014-06-04 19:54:15 +000067 _VSTD::__deallocate(__p);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000068 }
69 _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
70
Howard Hinnant333f50d2010-09-21 20:16:37 +000071 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000072 bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +000073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000074 bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;}
75};
76
77_LIBCPP_END_NAMESPACE_STD
78
79#endif // _LIBCPP___SSO_ALLOCATOR