xref: /openbsd-src/gnu/llvm/libcxx/src/include/sso_allocator.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
976d0caaeSpatrick 
1076d0caaeSpatrick #ifndef _LIBCPP_SSO_ALLOCATOR_H
1176d0caaeSpatrick #define _LIBCPP_SSO_ALLOCATOR_H
1276d0caaeSpatrick 
1376d0caaeSpatrick #include <__config>
1476d0caaeSpatrick #include <memory>
1576d0caaeSpatrick #include <new>
1676d0caaeSpatrick #include <type_traits>
1776d0caaeSpatrick 
1876d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1976d0caaeSpatrick #pragma GCC system_header
2076d0caaeSpatrick #endif
2176d0caaeSpatrick 
2276d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
2376d0caaeSpatrick 
2476d0caaeSpatrick template <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
2576d0caaeSpatrick 
2676d0caaeSpatrick template <size_t _Np>
2776d0caaeSpatrick class _LIBCPP_HIDDEN __sso_allocator<void, _Np>
2876d0caaeSpatrick {
2976d0caaeSpatrick public:
3076d0caaeSpatrick     typedef const void*       const_pointer;
3176d0caaeSpatrick     typedef void              value_type;
3276d0caaeSpatrick };
3376d0caaeSpatrick 
3476d0caaeSpatrick template <class _Tp, size_t _Np>
3576d0caaeSpatrick class _LIBCPP_HIDDEN __sso_allocator
3676d0caaeSpatrick {
3776d0caaeSpatrick     typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
3876d0caaeSpatrick     bool __allocated_;
3976d0caaeSpatrick public:
4076d0caaeSpatrick     typedef size_t            size_type;
4176d0caaeSpatrick     typedef _Tp*              pointer;
4276d0caaeSpatrick     typedef _Tp               value_type;
4376d0caaeSpatrick 
44*4bdff4beSrobert     template <class U>
45*4bdff4beSrobert     struct rebind {
46*4bdff4beSrobert         using other = __sso_allocator<U, _Np>;
47*4bdff4beSrobert     };
48*4bdff4beSrobert 
__sso_allocator()4976d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
__sso_allocator(const __sso_allocator &)5076d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
__sso_allocator(const __sso_allocator<_Up,_Np> &)5176d0caaeSpatrick     template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
5276d0caaeSpatrick          : __allocated_(false) {}
5376d0caaeSpatrick private:
5476d0caaeSpatrick     __sso_allocator& operator=(const __sso_allocator&);
5576d0caaeSpatrick public:
5676d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = nullptr)
5776d0caaeSpatrick     {
5876d0caaeSpatrick         if (!__allocated_ && __n <= _Np)
5976d0caaeSpatrick         {
6076d0caaeSpatrick             __allocated_ = true;
6176d0caaeSpatrick             return (pointer)&buf_;
6276d0caaeSpatrick         }
6376d0caaeSpatrick         return allocator<_Tp>().allocate(__n);
6476d0caaeSpatrick     }
deallocate(pointer __p,size_type __n)6576d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
6676d0caaeSpatrick     {
6776d0caaeSpatrick         if (__p == (pointer)&buf_)
6876d0caaeSpatrick             __allocated_ = false;
6976d0caaeSpatrick         else
7076d0caaeSpatrick             allocator<_Tp>().deallocate(__p, __n);
7176d0caaeSpatrick     }
max_size()7276d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
7376d0caaeSpatrick 
7476d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
7576d0caaeSpatrick     bool operator==(const __sso_allocator& __a) const {return &buf_ == &__a.buf_;}
7676d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
7776d0caaeSpatrick     bool operator!=(const __sso_allocator& __a) const {return &buf_ != &__a.buf_;}
7876d0caaeSpatrick };
7976d0caaeSpatrick 
8076d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
8176d0caaeSpatrick 
8276d0caaeSpatrick #endif // _LIBCPP_SSO_ALLOCATOR_H
83