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: 99 [fund.ts.v3::memory.resource.syn] Status: New Submitter: Thomas Köppe Opened: 2020-02-28 Last modified: 2021-11-20

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

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 stdouter-namespace::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 99 [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 A:

  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 8.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 8.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