cplusplus / nbballot

Handling of NB comments in response to ballots
14 stars 4 forks source link

US 53-116 26.8.2 [generator.syn] pmr alias for `std::generator` #529

Closed wg21bot closed 1 year ago

wg21bot commented 1 year ago

Generator supports Allocators and appears to support pmr::allocator but does not have a pmr alias.

Proposed change:

Add a pmr::generator alias with appropriate defaults In 26.8.2 [generator.syn] insert

namespace pmr {
    template<class T>
      using generator = std::generator<T, polymorphic_allocator<T>>;
  }
JeffGarland commented 1 year ago

This will not act like a container -- hence it needs to be designed. LEWG needs to evaluate if this is needed. A paper motivating is likely required.

CaseyCarter commented 1 year ago

The allocator type is rebound from generators third template parameter, so the alias needs to be:

namespace pmr {
    template<class Ref, class V = void>
      using generator = std::generator<Ref, V, polymorphic_allocator<>>;
}

generator always rebinds the allocator type, so using the default template argument for polymorphic_allocator is sufficient.

The "will not act like a container" concern brought up in LWG discussion is that generator is not an allocator-aware container, notably not respecting propoagate_on_container_move_assignment (POCMA). A coroutine frame cannot be copied/moved, let alone copied/moved into a fresh allocation from a particular allocator. In effect, generator acts as if POCMA were always true. This would be dangerous in cases like:

std::pmr::vector<int> vec;
std::pmr::generator<int> gen;

std::pmr::generator<int> f(std::allocator_arg_t, std::polymorphic_allocator<>) {
  // ...
}

void g() {
  unsigned char buffer[4096];
  {
    std::pmr::vector<int> x{{1,2,3,4}, std::pmr::monotonic_buffer_resource{buffer, sizeof(buffer)}};
    vec = std::move(x); // reallocates with `vec`'s allocator
  }
  // buffer is no longer in use, safe to reuse
  {
    auto x = f(std::allocator_arg, mbr);
    gen = std::move(x); // doesn't reallocate
  }
  // buffer is still in use, _not_ safe to reuse
  // ...
  // buffer is destroyed on function return, leaving ::gen dangling
}

where std::pmr::generator cannot be used like the std::pmr containers.

Expert users who understand the lack of respect for POCMA can define an alias themselves, but it seems dangerous for the library to provide an alias to naive users.

brycelelbach commented 1 year ago

Addressed by P2787 https://github.com/cplusplus/papers/issues/1457

JeffGarland commented 1 year ago

Reviewed and approved at Issaquah -- see paper issue for details.

jwakely commented 1 year ago

Accepted.