This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 3411. [fund.ts.v3] Contradictory namespace rules in the Library Fundamentals TS

Section: 5.4 [fund.ts.v3::memory.resource.syn] Status: New Submitter: Thomas Köppe Opened: 2020-02-28 Last modified: 2021-12-02

Priority: 3

View all issues with New status.

Discussion:

Addresses: fund.ts.v3

The Library Fundamentals TS, N4840, contains a rule about the use of namespaces (paragraph 1), with the consequence:

> "This TS does not define `std::experimental::fundamentals_v3::pmr`"

However, the TS then goes on to define exactly that namespace.

At the time when the subclause memory.resource.syn was added, the IS didn't use to contain a namespace `pmr`. When the IS adopted that namespace and the TS was rebased, the namespace rule started conflicting with the material in the TS.

I do not have a workable proposed resolution at this point.

[2020-04-07 Issue Prioritization]

Priority to 3 after reflector discussion.

[2021-11-17; Jiang An comments and provides wording]

Given namespaces `std::chrono::experimental::fundamentals_v2` and `std::experimental::fundamentals_v2::pmr` are used in LFTS v2, I think that the intent is that

- the prefix `experimental::fundamentals_vN` is only added to a namespace specified by the standard, and

- every name specified by the standard in the outer namespace of that of the related component in the TS.

If we follow the convention, perhaps we should relocate `resource_adaptor` from `std::experimental::fundamentals_v3::pmr` to `std::pmr::experimental::fundamentals_v3` in LFTS v3. If it's decided that `resource_adaptor` shouldn't be relocated, I suppose that LWG 3411 can be by striking the wrong wording in 1.3 [fund.ts.v3::general.namespaces] and using qualified `std::pmr::memory_resource` when needed.

Proposed resolution:

This wording is relative to N4853.

> [Drafting Note: Two mutually exclusive options are prepared, depicted below by Option A and Option B, respectively.]

Option A:

1. Modify 1.3 [fund.ts.v3::general.namespaces] as indicated:

   > -2- Each header described in this technical specification shall import the contents of `outer-namespacestd::experimental::fundamentals_v3` into `outer-namespacestd::experimental` as if by

   > >     namespace outer-namespacestd::experimental::inline fundamentals_v3 {}

   > where `outer-namespace` is a namespace defined in the C++ Standard Library.

2. Modify 5.3 [fund.ts.v3::memory.type.erased.allocator], Table 5, as indicated:

   > Table 5 — Computed `memory_resource` for type-erased allocator
   > If the type of `alloc` is | then the value of `rptr` is
   > --- | ---
   > `[…]`
   > any other type meeting the requirements (C++20 ¶16.5.3.5) | a pointer to a value of type `pmr::experimental::resource_adaptor<A>` where `A` is the type of `alloc`. `rptr` remains valid only for the lifetime of `X`.
   > `[…]`

3. Modify 5.4 [fund.ts.v3::memory.resource.syn], header `<experimental/memory_resource>` synopsis, as indicated:

   >     namespace std::pmr::experimental::inline fundamentals_v3::pmr {
   >     […]
   >     } // namespace std::pmr::experimental::inline fundamentals_v3::pmr

Option B:

1. Modify 1.3 [fund.ts.v3::general.namespaces] as indicated:

   > -1- Since the extensions described in this technical specification are experimental and not part of the C++ standard library, they should not be declared directly within namespace `std`. Unless otherwise specified, all components described in this technical specification either:

   > 1. — modify an existing interface in the C++ Standard Library in-place,

   > 2. — are declared in a namespace whose name appends `::experimental::fundamentals_v3` to a namespace defined in the C++ Standard Library, such as `std` or `std::chrono`, or

   > 3. — are declared in a subnamespace of a namespace described in the previous bullet, whose name is not the same as an existing subnamespace of namespace `std`.

   > [Example: This TS does not define `std::experimental::fundamentals_v3::pmr` because the C++ Standard Library defines `std::pmr`. — end example]

2. Modify 4.2 [fund.ts.v3::func.wrap.func], class template `function` synopsis, as indicated:

   >     namespace std {
   >       namespace experimental::inline fundamentals_v3 {

   >         template<class> class function; // undefined

   >         template<class R, class... ArgTypes>
   >         class function<R(ArgTypes...)> {
   >         public:
   >           […]
   >           std::pmr::memory_resource* get_memory_resource() const noexcept;
   >         };
   >     […]
   >     } // namespace experimental::inline fundamentals_v3
   >     […]
   >     } // namespace std

3. Modify 5.3 [fund.ts.v3::memory.type.erased.allocator], Table 5, as indicated:

   > Table 5 — Computed `memory_resource` for type-erased allocator
   > If the type of `alloc` is | then the value of `rptr` is
   > --- | ---
   > `[…]`
   > any other type meeting the requirements (C++20 ¶16.5.3.5) | a pointer to a value of type `experimental::pmr::resource_adaptor<A>` where `A` is the type of `alloc`. `rptr` remains valid only for the lifetime of `X`.
   > `[…]`

4. Modify 5.5.1 [fund.ts.v3::memory.resource.adaptor.overview] as indicated:

   > -1- An instance of `resource_adaptor<Allocator>` is an adaptor that wraps a `std::pmr::memory_resource` interface around `Allocator`. […]

   > >     // The name resource_adaptor_imp is for exposition only.
   > >     template<class Allocator>
   > >     class resource_adaptor_imp : public std::pmr::memory_resource {
   > >     public:
   > >       […]

   > >       virtual bool do_is_equal(const std::pmr::memory_resource& other) const noexcept;
   > >     };

5. Modify 5.5.3 [fund.ts.v3::memory.resource.adaptor.mem] as indicated:

   >     -6- bool do_is_equal(const std::pmr::memory_resource& other) const noexcept;

   > > […]

6. Modify 7.2 [fund.ts.v3::futures.promise], class template `promise` synopsis, as indicated:

   >     namespace std {
   >       namespace experimental::inline fundamentals_v3 {

   >         template<class R>
   >         class promise {
   >         public:
   >           […]
   >           std::pmr::memory_resource* get_memory_resource() const noexcept;
   >         };
   >     […]
   >     } // namespace experimental::inline fundamentals_v3
   >     […]
   >     } // namespace std

7. Modify 7.3 [fund.ts.v3::futures.task], class template `packaged_task` synopsis, as indicated:

   >     namespace std {
   >       namespace experimental::inline fundamentals_v3 {

   >         template<class R, class... ArgTypes>
   >         class packaged_task<R(ArgTypes...)> {
   >         public:
   >           […]
   >           std::pmr::memory_resource* get_memory_resource() const noexcept;
   >         };
   >     […]
   >     } // namespace experimental::inline fundamentals_v3
   >     […]
   >     } // namespace std