1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <memory>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx {
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace rpc {
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Allocator adaptor that interposes construct() calls to convert value
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// initialization into default initialization. All standard containers
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// value-initialize their elements when constructed with a single size_type
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// argument or when grown by a call to resize. This allocator avoids potentially
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// costly value-initialization in these situations for value types that are
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// default constructible. As a consequence, elements of non-class types are left
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// uninitialized; this is desirable when using std::vector as a resizable
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// buffer, for example.
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator = std::allocator<T>>
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass DefaultInitializationAllocator : public Allocator {
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  typedef std::allocator_traits<Allocator> AllocatorTraits;
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  template <typename U>
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  struct rebind {
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    using other = DefaultInitializationAllocator<
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        U, typename AllocatorTraits::template rebind_alloc<U>>;
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  };
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using Allocator::Allocator;
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  template <typename U>
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void construct(U* pointer) noexcept(
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      std::is_nothrow_default_constructible<U>::value) {
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ::new (static_cast<void*>(pointer)) U;
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  template <typename U, typename... Args>
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void construct(U* pointer, Args&&... args) {
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    AllocatorTraits::construct(static_cast<Allocator&>(*this), pointer,
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                               std::forward<Args>(args)...);
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace rpc
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace pdx
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif  //  ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
48