# 标准库头文件 <memory_resource>

< cpp‎ | header

此头文件是动态内存管理库的一部分。

### 类
定义于命名空间 `std::pmr`
polymorphic_allocator (C++17) | 以 std::memory_resource 构造，支持基于它的运行时多态的分配器 (类模板)
memory_resource (C++17) | 一个抽象接口，用于各种封装内存资源的类 (类)
pool_options (C++17) | 一组池资源的构造函数选项 (类)
synchronized_pool_resource (C++17) | 线程安全的 std::pmr::memory_resource，用于管理具有不同块大小的池中的分配 (类)
unsynchronized_pool_resource (C++17) | 线程不安全的 std::pmr::memory_resource，用于管理具有不同块大小的池中的分配 (类)
monotonic_buffer_resource (C++17) | 一种特殊用途的 std::pmr::memory_resource，仅在资源被销毁时才释放所分配内存 (类)
### 函数
定义于命名空间 `std::pmr`
new_delete_resource (C++17) | 返回一个静态的程序范围 std::pmr::memory_resource，它使用全局 operator new 与 operator delete 分配和解分配内存 (函数)
null_memory_resource (C++17) | 返回一个不进行任何分配的静态 std::pmr::memory_resource (函数)
get_default_resource (C++17) | 获取缺省 std::pmr::memory_resource (函数)
set_default_resource (C++17) | 设置缺省 std::pmr::memory_resource (函数)

### 概要

    namespace std::pmr {
      // 类 memory_resource
      class memory_resource;

      bool operator==(const memory_resource& a, const memory_resource& b) noexcept;

      // 类模板 polymorphic_allocator
      template<class Tp> class polymorphic_allocator;

      template<class T1, class T2>
        bool operator==(const polymorphic_allocator<T1>& a,
                        const polymorphic_allocator<T2>& b) noexcept;

      // 全局内存资源
      memory_resource* new_delete_resource() noexcept;
      memory_resource* null_memory_resource() noexcept;
      memory_resource* set_default_resource(memory_resource* r) noexcept;
      memory_resource* get_default_resource() noexcept;

      // 池资源类
      struct pool_options;
      class synchronized_pool_resource;
      class unsynchronized_pool_resource;
      class monotonic_buffer_resource;
    }

#### 类 std::pmr::memory_resource

    namespace std::pmr {
      class memory_resource {
        static constexpr size_t max_align = alignof(max_align_t);   // 仅用于阐释

      public:
        memory_resource() = default;
        memory_resource(const memory_resource&) = default;
        virtual ~memory_resource();

        memory_resource& operator=(const memory_resource&) = default;

        [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align);
        void deallocate(void* p, size_t bytes, size_t alignment = max_align);

        bool is_equal(const memory_resource& other) const noexcept;

      private:
        virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
        virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;

        virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
      };
    }

#### 类模板 std::pmr::polymorphic_allocator

    namespace std::pmr {
      template<class Tp = byte> class polymorphic_allocator {
        memory_resource* memory_rsrc;       // 仅用于阐释

      public:
        using value_type = Tp;

        // 构造函数
        polymorphic_allocator() noexcept;
        polymorphic_allocator(memory_resource* r);

        polymorphic_allocator(const polymorphic_allocator& other) = default;

        template<class U>
          polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;

        polymorphic_allocator& operator=(const polymorphic_allocator&) = delete;

        // 成员函数
        [[nodiscard]] Tp* allocate(size_t n);
        void deallocate(Tp* p, size_t n);

        [[nodiscard]] void* allocate_bytes(size_t nbytes,
                                           size_t alignment = alignof(max_align_t));
        void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
        template<class T> [[nodiscard]] T* allocate_object(size_t n = 1);
        template<class T> void deallocate_object(T* p, size_t n = 1);
        template<class T, class... CtorArgs>
          [[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
        template<class T> void delete_object(T* p);

        template<class T, class... Args>
          void construct(T* p, Args&&... args);

        template<class T>
          void destroy(T* p); // 弃用

        polymorphic_allocator select_on_container_copy_construction() const;

        memory_resource* resource() const;
      };
    }

#### 类 std::pmr::pool_options

    namespace std::pmr {
      struct pool_options {
        size_t max_blocks_per_chunk = 0;
        size_t largest_required_pool_block = 0;
      };
    }

#### 类 std::pmr::synchronized_pool_resource

    namespace std::pmr {
      class synchronized_pool_resource : public memory_resource {
      public:
        synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);

        synchronized_pool_resource()
            : synchronized_pool_resource(pool_options(), get_default_resource()) {}
        explicit synchronized_pool_resource(memory_resource* upstream)
            : synchronized_pool_resource(pool_options(), upstream) {}
        explicit synchronized_pool_resource(const pool_options& opts)
            : synchronized_pool_resource(opts, get_default_resource()) {}

        synchronized_pool_resource(const synchronized_pool_resource&) = delete;
        virtual ~synchronized_pool_resource();

        synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete;

        void release();
        memory_resource* upstream_resource() const;
        pool_options options() const;

      protected:
        void* do_allocate(size_t bytes, size_t alignment) override;
        void do_deallocate(void* p, size_t bytes, size_t alignment) override;

        bool do_is_equal(const memory_resource& other) const noexcept override;
      };
    }

#### 类 std::pmr::unsynchronized_pool_resource

    namespace std::pmr {
      class unsynchronized_pool_resource : public memory_resource {
      public:
        unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);

        unsynchronized_pool_resource()
            : unsynchronized_pool_resource(pool_options(), get_default_resource()) {}
        explicit unsynchronized_pool_resource(memory_resource* upstream)
            : unsynchronized_pool_resource(pool_options(), upstream) {}
        explicit unsynchronized_pool_resource(const pool_options& opts)
            : unsynchronized_pool_resource(opts, get_default_resource()) {}

        unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete;
        virtual ~unsynchronized_pool_resource();

        unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete;

        void release();
        memory_resource* upstream_resource() const;
        pool_options options() const;

      protected:
        void* do_allocate(size_t bytes, size_t alignment) override;
        void do_deallocate(void* p, size_t bytes, size_t alignment) override;

        bool do_is_equal(const memory_resource& other) const noexcept override;
      };
    }

#### 类 std::pmr::monotonic_buffer_resource

    namespace std::pmr {
      class monotonic_buffer_resource : public memory_resource {
        memory_resource* upstream_rsrc;     // 仅用于阐释
        void* current_buffer;               // 仅用于阐释
        size_t next_buffer_size;            // 仅用于阐释

      public:
        explicit monotonic_buffer_resource(memory_resource* upstream);
        monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
        monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);

        monotonic_buffer_resource()
          : monotonic_buffer_resource(get_default_resource()) {}
        explicit monotonic_buffer_resource(size_t initial_size)
          : monotonic_buffer_resource(initial_size, get_default_resource()) {}
        monotonic_buffer_resource(void* buffer, size_t buffer_size)
          : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {}

        monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;

        virtual ~monotonic_buffer_resource();

        monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete;

        void release();
        memory_resource* upstream_resource() const;

      protected:
        void* do_allocate(size_t bytes, size_t alignment) override;
        void do_deallocate(void* p, size_t bytes, size_t alignment) override;

        bool do_is_equal(const memory_resource& other) const noexcept override;
      };
    }