__sso_allocator 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___SSO_ALLOCATOR
  10. #define _LIBCPP___SSO_ALLOCATOR
  11. #include <__config>
  12. #include <type_traits>
  13. #include <new>
  14. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  15. #pragma GCC system_header
  16. #endif
  17. _LIBCPP_BEGIN_NAMESPACE_STD
  18. template <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
  19. template <size_t _Np>
  20. class _LIBCPP_HIDDEN __sso_allocator<void, _Np>
  21. {
  22. public:
  23. typedef const void* const_pointer;
  24. typedef void value_type;
  25. };
  26. template <class _Tp, size_t _Np>
  27. class _LIBCPP_HIDDEN __sso_allocator
  28. {
  29. typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
  30. bool __allocated_;
  31. public:
  32. typedef size_t size_type;
  33. typedef _Tp* pointer;
  34. typedef _Tp value_type;
  35. _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
  36. _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
  37. template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
  38. : __allocated_(false) {}
  39. private:
  40. __sso_allocator& operator=(const __sso_allocator&);
  41. public:
  42. _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = 0)
  43. {
  44. if (!__allocated_ && __n <= _Np)
  45. {
  46. __allocated_ = true;
  47. return (pointer)&buf_;
  48. }
  49. return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
  50. }
  51. _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
  52. {
  53. if (__p == (pointer)&buf_)
  54. __allocated_ = false;
  55. else
  56. _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
  57. }
  58. _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
  59. _LIBCPP_INLINE_VISIBILITY
  60. bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;}
  61. _LIBCPP_INLINE_VISIBILITY
  62. bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;}
  63. };
  64. _LIBCPP_END_NAMESPACE_STD
  65. #endif // _LIBCPP___SSO_ALLOCATOR