|
214 | 214 | explicit in_place_index_t() = default;
|
215 | 215 | };
|
216 | 216 | template<size_t I> constexpr in_place_index_t<I> in_place_index{};
|
| 217 | + |
| 218 | + // nontype argument tag% |
| 219 | +\indexlibraryglobal{nontype_t}% |
| 220 | +\indexlibraryglobal{nontype} |
| 221 | + template<auto V> |
| 222 | + struct nontype_t { |
| 223 | + explicit nontype_t() = default; |
| 224 | + }; |
| 225 | + template<auto V> constexpr nontype_t<V> nontype{}; |
217 | 226 | }
|
218 | 227 | \end{codeblock}
|
219 | 228 |
|
|
10571 | 10580 | template<class R, class... ArgTypes>
|
10572 | 10581 | class move_only_function<R(ArgTypes...) @\cv{}@ @\placeholder{ref}@ noexcept(@\placeholder{noex}@)>; // \seebelow
|
10573 | 10582 |
|
| 10583 | + // \ref{func.wrap.ref}, non-owning wrapper |
| 10584 | + template<class... S> class function_ref; // \notdef, freestanding |
| 10585 | + template<class R, class... ArgTypes> |
| 10586 | + class function_ref<R(ArgTypes...) @\cv{}@ noexcept(@\placeholder{noex}@)>; // \seebelow, freestanding |
| 10587 | + |
10574 | 10588 | // \ref{func.search}, searchers
|
10575 | 10589 | template<class ForwardIterator1, class BinaryPredicate = equal_to<>>
|
10576 | 10590 | class default_searcher; // freestanding
|
@@ -13431,6 +13445,359 @@
|
13431 | 13445 | \end{itemdescr}
|
13432 | 13446 | \indextext{function object!wrapper|)}
|
13433 | 13447 |
|
| 13448 | +\rSec3[func.wrap.ref]{Non-owning wrapper} |
| 13449 | + |
| 13450 | +\rSec4[func.wrap.ref.general]{General} |
| 13451 | + |
| 13452 | +\pnum |
| 13453 | +The header provides partial specializations of \tcode{function_ref} |
| 13454 | +for each combination of the possible replacements of |
| 13455 | +the placeholders \cv{} and \placeholder{noex} where: |
| 13456 | + |
| 13457 | +\begin{itemize} |
| 13458 | +\item \cv{} is either const or empty, and |
| 13459 | +\item \placeholder{noex} is either \tcode{true} or \tcode{false}. |
| 13460 | +\end{itemize} |
| 13461 | + |
| 13462 | +\rSec4[func.wrap.ref.class]{Class template \tcode{function_ref}} |
| 13463 | + |
| 13464 | +\indexlibraryglobal{move_only_function}% |
| 13465 | +\begin{codeblock} |
| 13466 | +namespace std { |
| 13467 | + template<class... S> class function_ref; // \notdef |
| 13468 | + |
| 13469 | + template<class R, class... ArgTypes> |
| 13470 | + class function_ref<R(ArgTypes...) @\cv{}@ noexcept(@\placeholder{noex}@)> { |
| 13471 | + public: |
| 13472 | + // \ref{func.wrap.ref.ctor}, constructors and assignment operators |
| 13473 | + template<class F> function_ref(F*) noexcept; |
| 13474 | + template<class F> constexpr function_ref(F&&) noexcept; |
| 13475 | + template<auto f> constexpr function_ref(nontype_t<f>) noexcept; |
| 13476 | + template<auto f, class U> |
| 13477 | + constexpr function_ref(nontype_t<f>, U&&) noexcept; |
| 13478 | + template<auto f, class T> |
| 13479 | + constexpr function_ref(nontype_t<f>, @\cv{}@ T*) noexcept; |
| 13480 | + |
| 13481 | + constexpr function_ref(const function_ref&) noexcept = default; |
| 13482 | + constexpr function_ref& operator=(const function_ref&) noexcept = default; |
| 13483 | + template<class T> function_ref& operator=(T) = delete; |
| 13484 | + |
| 13485 | + // \ref{func.wrap.ref.inv}, invocation |
| 13486 | + R operator()(ArgTypes...) const noexcept(noex); |
| 13487 | + |
| 13488 | + private: |
| 13489 | + template<class... T> |
| 13490 | + static constexpr bool @\exposid{is-invocable-using}@ = @\seebelow@; // \expos |
| 13491 | + }; |
| 13492 | + |
| 13493 | + // \ref{func.wrap.ref.deduct}, deduction guides |
| 13494 | + template<class F> |
| 13495 | + function_ref(F*) -> function_ref<F>; |
| 13496 | + template<auto f> |
| 13497 | + function_ref(nontype_t<f>) -> function_ref<see below>; |
| 13498 | + template<auto f> |
| 13499 | + function_ref(nontype_t<f>, auto) -> function_ref<see below>; |
| 13500 | +} |
| 13501 | +\end{codeblock} |
| 13502 | + |
| 13503 | +\pnum |
| 13504 | +An object of class |
| 13505 | +\tcode{function_ref<R(Args...) \cv{} noexcept(\placeholder{noex})>} |
| 13506 | +stores |
| 13507 | +%FIXME: What is "thunk-ptr"? where did it come from? |
| 13508 | +a pointer to function \exposid{thunk-ptr} and |
| 13509 | +%FIXME: What is "bound-entity"? where did it come from? |
| 13510 | +an object \exposid{bound-entity}. |
| 13511 | +\exposid{bound-entity} has |
| 13512 | +an unspecified trivially copyable type \tcode{BoundEntityType}, that |
| 13513 | +models \libconcept{copyable} and |
| 13514 | +is capable of storing a pointer to object value or a pointer to function value. |
| 13515 | +The type of \exposid{thunk-ptr} is |
| 13516 | +\tcode{R(*)(BoundEntityType, Args\&\&...) noexcept(noex)}. |
| 13517 | + |
| 13518 | +\pnum |
| 13519 | +Each specialization of \tcode{function_ref} is |
| 13520 | +a trivially copyable type \ref{basic.types} that models \libconcept{copyable}. |
| 13521 | + |
| 13522 | +\pnum |
| 13523 | +Within this subclause, |
| 13524 | +\tcode{\placeholder{call-args}} is an argument pack with elements such that |
| 13525 | +\tcode{decltype((\placeholder{call-args}))...} denote |
| 13526 | +\tcode{Args\&\&...} respectively. |
| 13527 | + |
| 13528 | +\rSec4[func.wrap.ref.ctor]{Constructors and assignment operators} |
| 13529 | + |
| 13530 | +\indextext{function_ref::is-invocable-using@\tcode{function_ref::\exposid{is-invocable-using}}}% |
| 13531 | +\begin{itemdecl} |
| 13532 | +template<class... T> |
| 13533 | + static constexpr bool @\exposid{is-invocable-using}@ = @\seebelow@; |
| 13534 | +\end{itemdecl} |
| 13535 | + |
| 13536 | +\begin{itemdescr} |
| 13537 | +\pnum |
| 13538 | +If \placeholder{noex} is \tcode{true}, |
| 13539 | +\tcode{\exposid{is-invocable-using}<T...>} is equal to: |
| 13540 | +\begin{codeblock} |
| 13541 | +is_nothrow_invocable_r_v<R, T..., ArgTypes...> |
| 13542 | +\end{codeblock} |
| 13543 | +Otherwise, \tcode{\exposid{is-invocable-using}<T...>} is equal to: |
| 13544 | +\begin{codeblock} |
| 13545 | +is_invocable_r_v<R, T..., ArgTypes...> |
| 13546 | +\end{codeblock} |
| 13547 | +\end{itemdescr} |
| 13548 | + |
| 13549 | +\indexlibraryctor{function_ref}% |
| 13550 | +\begin{itemdecl} |
| 13551 | +template<class F> function_ref(F* f) noexcept; |
| 13552 | +\end{itemdecl} |
| 13553 | + |
| 13554 | +\begin{itemdescr} |
| 13555 | +\pnum |
| 13556 | +\constraints |
| 13557 | +\begin{itemize} |
| 13558 | +\item \tcode{is_function_v<F>} is \tcode{true}, and |
| 13559 | +\item \tcode{\exposid{is-invocable-using}<F>} is \tcode{true}. |
| 13560 | +\end{itemize} |
| 13561 | + |
| 13562 | +\pnum |
| 13563 | +\expects |
| 13564 | +\tcode{f} is not a null pointer. |
| 13565 | + |
| 13566 | +\pnum |
| 13567 | +\effects |
| 13568 | +Initializes |
| 13569 | +\exposid{bound-entity} with \tcode{f}, and |
| 13570 | +\exposid{thunk-ptr} with the address of a function \tcode{\placeholder{thunk}} |
| 13571 | +such that |
| 13572 | +\tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} |
| 13573 | +is expression-equivalent to |
| 13574 | +\tcode{invoke_r<R>(f, \placeholder{call-args}...)}. |
| 13575 | +\end{itemdescr} |
| 13576 | + |
| 13577 | +\indexlibraryctor{function_ref}% |
| 13578 | +\begin{itemdecl} |
| 13579 | +template<class F> constexpr function_ref(F&& f) noexcept; |
| 13580 | +\end{itemdecl} |
| 13581 | + |
| 13582 | +\begin{itemdescr} |
| 13583 | +\pnum |
| 13584 | +Let \tcode{T} be \tcode{remove_reference_t<F>}. |
| 13585 | + |
| 13586 | +\pnum |
| 13587 | +\constraints |
| 13588 | +\begin{itemize} |
| 13589 | +\item \tcode{remove_cvref_t<F>} is not the same type as \tcode{function_ref}, |
| 13590 | +\item \tcode{is_member_pointer_v<T>} is \tcode{false}, and |
| 13591 | +\item \tcode{\exposid{is-invocable-using}<\cv{} T\&>} is \tcode{true}. |
| 13592 | +\end{itemize} |
| 13593 | + |
| 13594 | +\pnum |
| 13595 | +\effects |
| 13596 | +Initializes |
| 13597 | +\exposid{bound-entity} with \tcode{addressof(f)}, and |
| 13598 | +\exposid{thunk-ptr} with the address of a function \tcode{\placeholder{thunk}} |
| 13599 | +such that |
| 13600 | +\tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} |
| 13601 | +is expression-equivalent to |
| 13602 | +\tcode{invoke_r<R>(static_cast<\cv{} T\&>(f), \placeholder{call-args}...)}. |
| 13603 | +\end{itemdescr} |
| 13604 | + |
| 13605 | +\indexlibraryctor{function_ref}% |
| 13606 | +\begin{itemdecl} |
| 13607 | +template<auto f> constexpr function_ref(nontype_t<f>) noexcept; |
| 13608 | +\end{itemdecl} |
| 13609 | + |
| 13610 | +\begin{itemdescr} |
| 13611 | +\pnum |
| 13612 | +Let \tcode{F} be \tcode{decltype(f)}. |
| 13613 | + |
| 13614 | +\pnum |
| 13615 | +\constraints |
| 13616 | +\tcode{\exposid{is-invocable-using}<F>} is \tcode{true}. |
| 13617 | + |
| 13618 | +\pnum |
| 13619 | +\mandates |
| 13620 | +If \tcode{is_pointer_v<F> || is_member_pointer_v<F>} is \tcode{true}, |
| 13621 | +then \tcode{f != nullptr} is \tcode{true}. |
| 13622 | + |
| 13623 | +\pnum |
| 13624 | +\effects |
| 13625 | +Initializes |
| 13626 | +\exposid{bound-entity} with a pointer to unspecified object or |
| 13627 | +null pointer value, and |
| 13628 | +\exposid{thunk-ptr} with the address of a function \tcode{\placeholder{thunk}} |
| 13629 | +such that |
| 13630 | +\tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} |
| 13631 | +is expression-equivalent to |
| 13632 | +\tcode{invoke_r<R>(f, \placeholder{call-args}...)}. |
| 13633 | +\end{itemdescr} |
| 13634 | + |
| 13635 | +\indexlibraryctor{function_ref}% |
| 13636 | +\begin{itemdecl} |
| 13637 | +template<auto f, class U> |
| 13638 | + constexpr function_ref(nontype_t<f>, U&& obj) noexcept; |
| 13639 | +\end{itemdecl} |
| 13640 | + |
| 13641 | +\begin{itemdescr} |
| 13642 | +\pnum |
| 13643 | +Let \tcode{T} be \tcode{remove_reference_t<U>} and |
| 13644 | +\tcode{F} be \tcode{decltype(f)}. |
| 13645 | + |
| 13646 | +\pnum |
| 13647 | +\constraints |
| 13648 | +\begin{itemize} |
| 13649 | +\item \tcode{is_rvalue_reference_v<U\&\&>} is \tcode{false}, and |
| 13650 | +\item \tcode{\exposid{is-invocable-using}<F, \cv{} T\&>} is \tcode{true}. |
| 13651 | +\end{itemize} |
| 13652 | + |
| 13653 | +\pnum |
| 13654 | +\mandates |
| 13655 | +If \tcode{is_pointer_v<F> || is_member_pointer_v<F>} is \tcode{true}, |
| 13656 | +then \tcode{f != nullptr} is \tcode{true}. |
| 13657 | + |
| 13658 | +\pnum |
| 13659 | +\effects |
| 13660 | +Initializes |
| 13661 | +\exposid{bound-entity} with \tcode{addressof(obj)}, and |
| 13662 | +\exposid{thunk-ptr} with the address of a function \tcode{\placeholder{thunk}} |
| 13663 | +such that |
| 13664 | +\tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} |
| 13665 | +is expression-equivalent to |
| 13666 | +\tcode{invoke_r<R>(f, static_cast<\cv{} T\&>(obj), \placeholder{call-args}...)}. |
| 13667 | +\end{itemdescr} |
| 13668 | + |
| 13669 | +\indexlibraryctor{function_ref}% |
| 13670 | +\begin{itemdecl} |
| 13671 | +template<auto f, class T> |
| 13672 | + constexpr function_ref(nontype_t<f>, @\cv{}@ T* obj) noexcept; |
| 13673 | +\end{itemdecl} |
| 13674 | + |
| 13675 | +\begin{itemdescr} |
| 13676 | +\pnum |
| 13677 | +Let \tcode{F} be \tcode{decltype(f)}. |
| 13678 | + |
| 13679 | +\pnum |
| 13680 | +\constraints |
| 13681 | +\tcode{\exposid{is-invocable-using}<F, \cv{} T*>} is \tcode{true}. |
| 13682 | + |
| 13683 | +\pnum |
| 13684 | +\mandates |
| 13685 | +If \tcode{is_pointer_v<F> || is_member_pointer_v<F>} is \tcode{true}, |
| 13686 | +then \tcode{f != nullptr} is \tcode{true}. |
| 13687 | + |
| 13688 | +\pnum |
| 13689 | +\expects |
| 13690 | +If \tcode{is_member_pointer_v<F>} is \tcode{true}, |
| 13691 | +\tcode{obj} is not a null pointer. |
| 13692 | + |
| 13693 | +\pnum |
| 13694 | +\effects |
| 13695 | +Initializes |
| 13696 | +\exposid{bound-entity} with \tcode{obj}, and |
| 13697 | +\exposid{thunk-ptr} with the address of a function \tcode{\placeholder{thunk}} |
| 13698 | +such that |
| 13699 | +\tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} |
| 13700 | +is expression-equivalent to |
| 13701 | +\tcode{invoke_r<R>(f, obj, \placeholder{call-args}...)}. |
| 13702 | +\end{itemdescr} |
| 13703 | + |
| 13704 | +\indexlibrarymember{operator=}{function_ref}% |
| 13705 | +\begin{itemdecl} |
| 13706 | +template<class T> function_ref& operator=(T) = delete; |
| 13707 | +\end{itemdecl} |
| 13708 | + |
| 13709 | +\begin{itemdescr} |
| 13710 | +\pnum |
| 13711 | +\constraints |
| 13712 | +\begin{itemize} |
| 13713 | +\item \tcode{T} is not the same type as \tcode{function_ref}, |
| 13714 | +\item \tcode{is_pointer_v<T>} is \tcode{false}, and |
| 13715 | +\item \tcode{T} is not a specialization of \tcode{nontype_t}. |
| 13716 | +\end{itemize} |
| 13717 | +\end{itemdescr} |
| 13718 | + |
| 13719 | +\rSec4[func.wrap.ref.inv]{Invocation} |
| 13720 | + |
| 13721 | +\indexlibrarymember{operator()}{function_ref}% |
| 13722 | +\begin{itemdecl} |
| 13723 | +R operator()(ArgTypes... args) const noexcept(@\placeholder{noex}@); |
| 13724 | +\end{itemdecl} |
| 13725 | + |
| 13726 | +\begin{itemdescr} |
| 13727 | +\pnum |
| 13728 | +\effects |
| 13729 | +Equivalent to: |
| 13730 | +\tcode{return \exposid{thunk-ptr}(\exposid{bound-entity}, std::forward<ArgTypes>(args)...);} |
| 13731 | +\end{itemdescr} |
| 13732 | + |
| 13733 | +\rSec4[func.wrap.ref.deduct]{Deduction guides} |
| 13734 | + |
| 13735 | +\indexlibrarymember{operator()}{function_ref}% |
| 13736 | +\begin{itemdecl} |
| 13737 | +template<class F> |
| 13738 | + function_ref(F*) -> function_ref<F>; |
| 13739 | +\end{itemdecl} |
| 13740 | + |
| 13741 | +\begin{itemdescr} |
| 13742 | +\pnum |
| 13743 | +\constraints |
| 13744 | +\tcode{is_function_v<F>} is \tcode{true}. |
| 13745 | +\end{itemdescr} |
| 13746 | + |
| 13747 | +\indexlibrarymember{operator()}{function_ref}% |
| 13748 | +\begin{itemdecl} |
| 13749 | +template<auto f> |
| 13750 | + function_ref(nontype_t<f>) -> function_ref<@\seebelow@>; |
| 13751 | +\end{itemdecl} |
| 13752 | + |
| 13753 | +\begin{itemdescr} |
| 13754 | +\pnum |
| 13755 | +Let \tcode{F} be \tcode{remove_pointer_t<decltype(f)>}. |
| 13756 | + |
| 13757 | +\pnum |
| 13758 | +\constraints |
| 13759 | +\tcode{is_function_v<F>} is \tcode{true}. |
| 13760 | + |
| 13761 | +\pnum |
| 13762 | +\remarks |
| 13763 | +The deduced type is \tcode{function_ref<F>}. |
| 13764 | +\end{itemdescr} |
| 13765 | + |
| 13766 | +\indexlibrarymember{operator()}{function_ref}% |
| 13767 | +\begin{itemdecl} |
| 13768 | +template<auto f, class T> |
| 13769 | + function_ref(nontype_t<f>, T&&) -> function_ref<@\seebelow@>; |
| 13770 | +\end{itemdecl} |
| 13771 | + |
| 13772 | +\begin{itemdescr} |
| 13773 | +\pnum |
| 13774 | +Let \tcode{F} be \tcode{decltype(f)}. |
| 13775 | + |
| 13776 | +\pnum |
| 13777 | +\constraints |
| 13778 | +%FIXME: R and E should be defined outside of these constraints. |
| 13779 | +%FIXME: Define R and E via "let" in paragraph above, then use them here and below. |
| 13780 | +\begin{itemize} |
| 13781 | +\item |
| 13782 | +\tcode{F} is of the form |
| 13783 | +\tcode{R(G::*)(A...) \cv{} \opt{\&} noexcept(E)} for a type \tcode{G}, or |
| 13784 | +\item |
| 13785 | +\tcode{F} is of the form |
| 13786 | +\tcode{M G::*} for a type \tcode{G} and an object type \tcode{M}, |
| 13787 | +in which case |
| 13788 | +let \tcode{R} be \tcode{invoke_result_t<F, T\&>}, |
| 13789 | +\tcode{A...} be an empty pack, and |
| 13790 | +\tcode{E} be \tcode{false}, or |
| 13791 | +\item |
| 13792 | +\tcode{F} is of the form |
| 13793 | +\tcode{R(*)(G, A...) noexcept(E)} for a type \tcode{G}. |
| 13794 | +\end{itemize} |
| 13795 | + |
| 13796 | +\pnum |
| 13797 | +\remarks |
| 13798 | +The deduced type is \tcode{function_ref<R(A...) noexcept(E)>}. |
| 13799 | +\end{itemdescr} |
| 13800 | + |
13434 | 13801 | \rSec2[func.search]{Searchers}
|
13435 | 13802 |
|
13436 | 13803 | \rSec3[func.search.general]{General}
|
|
0 commit comments