Namespaces
Variants
Actions

std::indirectly_writable

From cppreference.com
< cpp‎ | iterator
 
 
Iterator library
Iterator concepts
indirectly_writable
(C++20)
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 
Defined in header <iterator>
template<class Out, class T >

    concept indirectly_writable =
        requires(Out&& o, T&& t){
            *o =std::forward<T>(t);
            *std::forward<Out>(o)=std::forward<T>(t);
            const_cast<conststd::iter_reference_t<Out>&&>(*o)=std::forward<T>(t);
            const_cast<conststd::iter_reference_t<Out>&&>(*std::forward<Out>(o))=
                std::forward<T>(t);
        };

        /* none of the four expressions above are required to be equality-preserving */
(since C++20)

The concept indirectly_writable<Out, T> specifies the requirements for writing a value whose type and value category are encoded by T into an iterator Out's referenced object.

[edit]Semantic requirements

Let e be an expression such that decltype((e)) is T, and o be a dereferenceable object of type Out, then indirectly_writable<Out, T> is modeled only if:

o is not required to be dereferenceable after evaluating any of the assignment expressions above. If e is an xvalue, the resulting state of the object it denotes is valid but unspecified.

[edit]Equality preservation

Expressions declared in requires expressions of the standard library concepts are required to be equality-preserving (except where stated otherwise).

[edit]Notes

The only valid use of operator* is on the left side of an assignment expression. Assignment through the same value of an indirectly writable type may happen only once.

The required expressions with const_cast prevent indirectly_readable objects with prvalue reference types from satisfying the syntactic requirements of indirectly_writable by accident, while permitting proxy references to continue to work as long as their constness is shallow. See Ranges TS issue 381.

struct Object { Object& operator=(const Object& other)=default;   int x;};   struct ProxyReference { ProxyReference& operator=(const ProxyReference& other)=default;   const ProxyReference& operator=(const Object& o)const{*p = o;return*this;}   Object* p;};   struct I1 { Object& operator*();};   struct I2 { Object operator*();};   struct I3 { ProxyReference operator*();};   static_assert(std::indirectly_writable<I1, Object>); static_assert(!std::indirectly_writable<I2, Object>); static_assert(std::indirectly_writable<I3, Object>); static_assert(!std::indirectly_writable<I3, ProxyReference>);   void f(I1 i1, I2 i2, I3 i3, Object o){*i1 = o;// OK, assigns to the value referenced by *i1   *i2 = o;// OK, but meaningless: This assigns to the temporary returned by *i2   *i3 = o;// OK, calls ProxyReference::operator=(const Object& o) const// which performs *ptr = o, where ptr is (*i3).p}
close