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