17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===----------------------------------------------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP___SSO_ALLOCATOR
127a984708SDavid Chisnall#define _LIBCPP___SSO_ALLOCATOR
137a984708SDavid Chisnall
147a984708SDavid Chisnall#include <__config>
157a984708SDavid Chisnall#include <type_traits>
167a984708SDavid Chisnall#include <new>
177a984708SDavid Chisnall
187a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
197a984708SDavid Chisnall#pragma GCC system_header
207a984708SDavid Chisnall#endif
217a984708SDavid Chisnall
227a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
237a984708SDavid Chisnall
2494e3ee44SDavid Chisnalltemplate <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
257a984708SDavid Chisnall
2694e3ee44SDavid Chisnalltemplate <size_t _Np>
2794e3ee44SDavid Chisnallclass _LIBCPP_HIDDEN __sso_allocator<void, _Np>
287a984708SDavid Chisnall{
297a984708SDavid Chisnallpublic:
307a984708SDavid Chisnall    typedef const void*       const_pointer;
317a984708SDavid Chisnall    typedef void              value_type;
327a984708SDavid Chisnall};
337a984708SDavid Chisnall
3494e3ee44SDavid Chisnalltemplate <class _Tp, size_t _Np>
357a984708SDavid Chisnallclass _LIBCPP_HIDDEN __sso_allocator
367a984708SDavid Chisnall{
3794e3ee44SDavid Chisnall    typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
387a984708SDavid Chisnall    bool __allocated_;
397a984708SDavid Chisnallpublic:
407a984708SDavid Chisnall    typedef size_t            size_type;
417a984708SDavid Chisnall    typedef _Tp*              pointer;
427a984708SDavid Chisnall    typedef _Tp               value_type;
437a984708SDavid Chisnall
447a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
457a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
4694e3ee44SDavid Chisnall    template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
477a984708SDavid Chisnall         : __allocated_(false) {}
487a984708SDavid Chisnallprivate:
497a984708SDavid Chisnall    __sso_allocator& operator=(const __sso_allocator&);
507a984708SDavid Chisnallpublic:
5194e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = 0)
527a984708SDavid Chisnall    {
5394e3ee44SDavid Chisnall        if (!__allocated_ && __n <= _Np)
547a984708SDavid Chisnall        {
557a984708SDavid Chisnall            __allocated_ = true;
567a984708SDavid Chisnall            return (pointer)&buf_;
577a984708SDavid Chisnall        }
58*b5893f02SDimitry Andric        return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
597a984708SDavid Chisnall    }
60*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
617a984708SDavid Chisnall    {
627a984708SDavid Chisnall        if (__p == (pointer)&buf_)
637a984708SDavid Chisnall            __allocated_ = false;
647a984708SDavid Chisnall        else
65*b5893f02SDimitry Andric            _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
667a984708SDavid Chisnall    }
677a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
687a984708SDavid Chisnall
697a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
707a984708SDavid Chisnall    bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;}
717a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
727a984708SDavid Chisnall    bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;}
737a984708SDavid Chisnall};
747a984708SDavid Chisnall
757a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
767a984708SDavid Chisnall
777a984708SDavid Chisnall#endif  // _LIBCPP___SSO_ALLOCATOR
78