C++ Extensions for Library Fundamentals, Version 2, Working Draft

Document Number: | N4084
Date: | 2014-07-06
Editor: | Jeffrey Yasskin Google, Inc. jyasskin@google.com

# Working Draft, C++ Extensions for Library Fundamentals, Version 2

Note: this is an early draft. It’s known to be incomplet and incorrekt, and it has lots of bad formatting.

1

# General

[general]
1.1

# Scope

[general.scope]

This technical specification describes extensions to the C++ Standard Library (1.2). These extensions are classes and functions that are likely to be used widely within a program and/or on the interface boundaries between libraries written by different organizations.

This technical specification is non-normative. Some of the library components in this technical specification may be considered for standardization in a future version of C++, but they are not currently part of any C++ standard. Some of the components in this technical specification may never be standardized, and others may be standardized in a substantially changed form.

The goal of this technical specification is to build more widespread existing practice for an expanded C++ standard library. It gives advice on extensions to those vendors who wish to provide them.

1.2

# Normative references

[general.references]

The following referenced document is indispensable for the application of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

- ISO/IEC 14882:—1
  1) To be published. Section references are relative to N3937.
  , Programming Languages — C++

ISO/IEC 14882:— is herein called the C++ Standard. References to clauses within the C++ Standard are written as "C++14 §3.2". The library described in ISO/IEC 14882:— clauses 17–30 is herein called the C++ Standard Library.

Unless otherwise specified, the whole of the C++ Standard's Library introduction (C++14 §17) is included into this Technical Specification by reference.

1.3

# Namespaces, headers, and modifications to standard classes

[general.namespaces]

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:

- modify an existing interface in the C++ Standard Library in-place,
- are declared in a namespace whose name appends `::experimental::fundamentals_v2` to a namespace defined in the C++ Standard Library, such as `std` or `std::chrono`, or
- 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_v2::chrono` because the C++ Standard Library defines `std::chrono`. This TS does not define `std::pmr::experimental::fundamentals_v2` because the C++ Standard Library does not define `std::pmr`. — end example ]

Each header described in this technical specification shall import the contents of `std::experimental::fundamentals_v2` into `std::experimental` as if by

    namespace std {
      namespace experimental {
        inline namespace fundamentals_v2 {}
      }
    }

Unless otherwise specified, references to other entities described in this technical specification are assumed to be qualified with `std::experimental::fundamentals_v2::`, and references to entities described in the standard are assumed to be qualified with `std::`.

Extensions that are expected to eventually be added to an existing header `<meow>` are provided inside the `<experimental/meow>` header, which shall include the standard contents of `<meow>` as if by

    #include <meow>

New headers are also provided in the `<experimental/>` directory, but without such an `#include`.

Table 1 — C++ library headers
`<experimental/functional>` |  |

1.4

# Future plans (Informative)

[general.plans]

This section describes tentative plans for future versions of this technical specification and plans for moving content into future versions of the C++ Standard.

The C++ committee intends to release a new version of this technical specification approximately every year, containing the library extensions we hope to add to a near-future version of the C++ Standard. Future versions will define their contents in `std::experimental::fundamentals_v3`, `std::experimental::fundamentals_v4`, etc., with the most recent implemented version inlined into `std::experimental`.

When an extension defined in this or a future version of this technical specification represents enough existing practice, it will be moved into the next version of the C++ Standard by removing the `experimental::fundamentals_vN` segment of its namespace and by removing the `experimental/` prefix from its header's path.

1.5

# Feature-testing recommendations (Informative)

[general.feature.test]

For the sake of improved portability between partial implementations of various C++ standards, WG21 (the ISO technical committee for the C++ programming language) recommends that implementers and programmers follow the guidelines in this section concerning feature-test macros. [ Note: WG21's SD-6 makes similar recommendations for the C++ Standard itself. — end note ]

Implementers who provide a new standard feature should define a macro with the recommended name, in the same circumstances under which the feature is available (for example, taking into account relevant command-line options), to indicate the presence of support for that feature. Implementers should define that macro with the value specified in the most recent version of this technical specification that they have implemented. The recommended macro name is "`__cpp_lib_experimental_`" followed by the string in the "Macro Name Suffix" column.

Programmers who wish to determine whether a feature is available in an implementation should base that determination on the presence of the header (determined with `__has_include(<header/name>)`) and the state of the macro with the recommended name. (The absence of a tested feature may result in a program with decreased functionality, or the relevant functionality may be provided in a different way. A program that strictly depends on support for a feature can just try to use the feature unconditionally; presumably, on an implementation lacking necessary support, translation will fail.)

Table 2 — Significant features in this technical specification
Doc. No. | Title | Primary Section | Macro Name Suffix | Value | Header
--- | --- | --- | --- | --- | ---
N4076 | A proposal to add a generalized callable negator | 2.2 | `not_fn` | 201406 | `<experimental/functional>`

2

# Function objects

[func]
2.1

# Header `<experimental/functional>` synopsis

[header.functional.synop]

    #include <functional>

    namespace std {
    namespace experimental {
    inline namespace fundamentals_v2 {

      // 2.2, Function template not_fn
      template <class F> unspecified not_fn(F&& f);

    } // namespace fundamentals_v2
    } // namespace experimental
    } // namespace std

2.2

# Function template `not_fn`

[func.not_fn]

    template <class F> unspecified not_fn(F&& f);

In the text that follows:

- `FD` is the type `decay_t<F>`,
- `fd` is an lvalue of type `FD` constructed from `std::forward<F>(f),`
- `fn` is a forwarding call wrapper created as a result of `not_fn(f)`,

Requires:
  `is_constructible<FD, F>::value` shall be `true`. `fd` shall be a callable object (C++14 §20.9.1).
Returns:
  A forwarding call wrapper `fn` such that the expression `fn(a1, a2, ..., aN)` is equivalent to `!INVOKE(fd, a1, a2, ..., aN)` (C++14 §20.9.2).
Throws:
  Nothing unless the construction of `fd` throws an exception.
Remarks:
  The return type shall satisfy the requirements of `MoveConstructible`. If `FD` satisfies the requirements of `CopyConstructible`, then the return type shall satisfy the requirements of `CopyConstructible`. [ Note: This implies that `FD` is MoveConstructible. — end note ]

[ Note: Function template `not_fn` can usually provide a better solution than using the negators `not1` and `not2` — end note ]