diff --git a/source/iterators.tex b/source/iterators.tex index 8a2967da6c..43909eeb88 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -31,6 +31,7 @@ \indexheader{iterator}% \begin{codeblock} +// mostly freestanding #include // see \ref{compare.syn} #include // see \ref{concepts.syn} #include // see \ref{initializer.list.syn} @@ -46,30 +47,30 @@ // \ref{iterator.assoc.types}, associated types // \ref{incrementable.traits}, incrementable traits - template struct incrementable_traits; // freestanding + template struct incrementable_traits; template - using iter_difference_t = @\seebelow@; // freestanding + using iter_difference_t = @\seebelow@; // \ref{readable.traits}, indirectly readable traits - template struct indirectly_readable_traits; // freestanding + template struct indirectly_readable_traits; template - using iter_value_t = @\seebelow@; // freestanding + using iter_value_t = @\seebelow@; // \ref{iterator.traits}, iterator traits - template struct iterator_traits; // freestanding - template requires is_object_v struct iterator_traits; // freestanding + template struct iterator_traits; + template requires is_object_v struct iterator_traits; template<@\exposconcept{dereferenceable}@ T> - using @\libglobal{iter_reference_t}@ = decltype(*declval()); // freestanding + using @\libglobal{iter_reference_t}@ = decltype(*declval()); namespace ranges { // \ref{iterator.cust}, customization point objects inline namespace @\unspec@ { // \ref{iterator.cust.move}, \tcode{ranges::iter_move} - inline constexpr @\unspec@ iter_move = @\unspec@; // freestanding + inline constexpr @\unspec@ iter_move = @\unspec@; // \ref{iterator.cust.swap}, \tcode{ranges::iter_swap} - inline constexpr @\unspec@ iter_swap = @\unspec@; // freestanding + inline constexpr @\unspec@ iter_swap = @\unspec@; } } @@ -77,452 +78,449 @@ requires requires(T& t) { { ranges::iter_move(t) } -> @\exposconcept{can-reference}@; } - using @\libglobal{iter_rvalue_reference_t}@ // freestanding + using @\libglobal{iter_rvalue_reference_t}@ = decltype(ranges::iter_move(declval())); // \ref{iterator.concepts}, iterator concepts // \ref{iterator.concept.readable}, concept \libconcept{indirectly_readable} template - concept indirectly_readable = @\seebelow@; // freestanding + concept indirectly_readable = @\seebelow@; // \ref{indirectcallable.traits}, indirect callable traits template<@\libconcept{indirectly_readable}@ T> using @\exposidnc{indirect-value-t}@ = @\seebelow@; // \expos template<@\libconcept{indirectly_readable}@ T> - using @\libglobal{iter_common_reference_t}@ = // freestanding + using @\libglobal{iter_common_reference_t}@ = common_reference_t, @\exposid{indirect-value-t}@>; // \ref{iterator.concept.writable}, concept \libconcept{indirectly_writable} template - concept indirectly_writable = @\seebelow@; // freestanding + concept indirectly_writable = @\seebelow@; // \ref{iterator.concept.winc}, concept \libconcept{weakly_incrementable} template - concept weakly_incrementable = @\seebelow@; // freestanding + concept weakly_incrementable = @\seebelow@; // \ref{iterator.concept.inc}, concept \libconcept{incrementable} template - concept incrementable = @\seebelow@; // freestanding + concept incrementable = @\seebelow@; // \ref{iterator.concept.iterator}, concept \libconcept{input_or_output_iterator} template - concept input_or_output_iterator = @\seebelow@; // freestanding + concept input_or_output_iterator = @\seebelow@; // \ref{iterator.concept.sentinel}, concept \libconcept{sentinel_for} template - concept sentinel_for = @\seebelow@; // freestanding + concept sentinel_for = @\seebelow@; // \ref{iterator.concept.sizedsentinel}, concept \libconcept{sized_sentinel_for} template - constexpr bool disable_sized_sentinel_for = false; // freestanding + constexpr bool disable_sized_sentinel_for = false; template - concept sized_sentinel_for = @\seebelow@; // freestanding + concept sized_sentinel_for = @\seebelow@; // \ref{iterator.concept.input}, concept \libconcept{input_iterator} template - concept input_iterator = @\seebelow@; // freestanding + concept input_iterator = @\seebelow@; // \ref{iterator.concept.output}, concept \libconcept{output_iterator} template - concept output_iterator = @\seebelow@; // freestanding + concept output_iterator = @\seebelow@; // \ref{iterator.concept.forward}, concept \libconcept{forward_iterator} template - concept forward_iterator = @\seebelow@; // freestanding + concept forward_iterator = @\seebelow@; // \ref{iterator.concept.bidir}, concept \libconcept{bidirectional_iterator} template - concept bidirectional_iterator = @\seebelow@; // freestanding + concept bidirectional_iterator = @\seebelow@; // \ref{iterator.concept.random.access}, concept \libconcept{random_access_iterator} template - concept random_access_iterator = @\seebelow@; // freestanding + concept random_access_iterator = @\seebelow@; // \ref{iterator.concept.contiguous}, concept \libconcept{contiguous_iterator} template - concept contiguous_iterator = @\seebelow@; // freestanding + concept contiguous_iterator = @\seebelow@; // \ref{indirectcallable}, indirect callable requirements // \ref{indirectcallable.indirectinvocable}, indirect callables template - concept indirectly_unary_invocable = @\seebelow@; // freestanding + concept indirectly_unary_invocable = @\seebelow@; template - concept indirectly_regular_unary_invocable = @\seebelow@; // freestanding + concept indirectly_regular_unary_invocable = @\seebelow@; template - concept indirect_unary_predicate = @\seebelow@; // freestanding + concept indirect_unary_predicate = @\seebelow@; template - concept indirect_binary_predicate = @\seebelow@; // freestanding + concept indirect_binary_predicate = @\seebelow@; template - concept indirect_equivalence_relation = @\seebelow@; // freestanding + concept indirect_equivalence_relation = @\seebelow@; template - concept indirect_strict_weak_order = @\seebelow@; // freestanding + concept indirect_strict_weak_order = @\seebelow@; template requires (@\libconcept{indirectly_readable}@ && ...) && @\libconcept{invocable}@...> - using @\libglobal{indirect_result_t}@ = invoke_result_t...>; // freestanding + using @\libglobal{indirect_result_t}@ = invoke_result_t...>; // \ref{projected}, projected template<@\libconcept{indirectly_readable}@ I, @\libconcept{indirectly_regular_unary_invocable}@ Proj> - using projected = @\seebelow@; // freestanding + using projected = @\seebelow@; template<@\libconcept{indirectly_readable}@ I, @\libconcept{indirectly_regular_unary_invocable}@ Proj> - using projected_value_t = // freestanding + using projected_value_t = remove_cvref_t&>>; // \ref{alg.req}, common algorithm requirements // \ref{alg.req.ind.move}, concept \libconcept{indirectly_movable} template - concept indirectly_movable = @\seebelow@; // freestanding + concept indirectly_movable = @\seebelow@; template - concept indirectly_movable_storable = @\seebelow@; // freestanding + concept indirectly_movable_storable = @\seebelow@; // \ref{alg.req.ind.copy}, concept \libconcept{indirectly_copyable} template - concept indirectly_copyable = @\seebelow@; // freestanding + concept indirectly_copyable = @\seebelow@; template - concept indirectly_copyable_storable = @\seebelow@; // freestanding + concept indirectly_copyable_storable = @\seebelow@; // \ref{alg.req.ind.swap}, concept \libconcept{indirectly_swappable} template - concept indirectly_swappable = @\seebelow@; // freestanding + concept indirectly_swappable = @\seebelow@; // \ref{alg.req.ind.cmp}, concept \libconcept{indirectly_comparable} template - concept indirectly_comparable = @\seebelow@; // freestanding + concept indirectly_comparable = @\seebelow@; // \ref{alg.req.permutable}, concept \libconcept{permutable} template - concept permutable = @\seebelow@; // freestanding + concept permutable = @\seebelow@; // \ref{alg.req.mergeable}, concept \libconcept{mergeable} template - concept mergeable = @\seebelow@; // freestanding + concept mergeable = @\seebelow@; // \ref{alg.req.sortable}, concept \libconcept{sortable} template - concept sortable = @\seebelow@; // freestanding + concept sortable = @\seebelow@; // \ref{iterator.primitives}, primitives // \ref{std.iterator.tags}, iterator tags - struct input_iterator_tag { }; // freestanding - struct output_iterator_tag { }; // freestanding - struct forward_iterator_tag: public input_iterator_tag { }; // freestanding - struct bidirectional_iterator_tag: public forward_iterator_tag { }; // freestanding - struct random_access_iterator_tag: public bidirectional_iterator_tag { }; // freestanding - struct contiguous_iterator_tag: public random_access_iterator_tag { }; // freestanding + struct input_iterator_tag { }; + struct output_iterator_tag { }; + struct forward_iterator_tag: public input_iterator_tag { }; + struct bidirectional_iterator_tag: public forward_iterator_tag { }; + struct random_access_iterator_tag: public bidirectional_iterator_tag { }; + struct contiguous_iterator_tag: public random_access_iterator_tag { }; // \ref{iterator.operations}, iterator operations template constexpr void - advance(InputIterator& i, Distance n); // freestanding + advance(InputIterator& i, Distance n); template constexpr typename iterator_traits::difference_type - distance(InputIterator first, InputIterator last); // freestanding + distance(InputIterator first, InputIterator last); template constexpr InputIterator - next(InputIterator x, // freestanding + next(InputIterator x, typename iterator_traits::difference_type n = 1); template constexpr BidirectionalIterator - prev(BidirectionalIterator x, // freestanding + prev(BidirectionalIterator x, typename iterator_traits::difference_type n = 1); // \ref{range.iter.ops}, range iterator operations namespace ranges { // \ref{range.iter.op.advance}, \tcode{ranges::advance} template<@\libconcept{input_or_output_iterator}@ I> - constexpr void advance(I& i, iter_difference_t n); // freestanding + constexpr void advance(I& i, iter_difference_t n); template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr void advance(I& i, S bound); // freestanding + constexpr void advance(I& i, S bound); template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr iter_difference_t advance(I& i, iter_difference_t n, // freestanding - S bound); + constexpr iter_difference_t advance(I& i, iter_difference_t n, S bound); // \ref{range.iter.op.distance}, \tcode{ranges::distance} template S> requires (!@\libconcept{sized_sentinel_for}@) - constexpr iter_difference_t distance(I first, S last); // freestanding + constexpr iter_difference_t distance(I first, S last); template> S> - constexpr iter_difference_t> distance(I&& first, S last); // freestanding + constexpr iter_difference_t> distance(I&& first, S last); template<@\libconcept{range}@ R> - constexpr range_difference_t distance(R&& r); // freestanding + constexpr range_difference_t distance(R&& r); // \ref{range.iter.op.next}, \tcode{ranges::next} template<@\libconcept{input_or_output_iterator}@ I> - constexpr I next(I x); // freestanding + constexpr I next(I x); template<@\libconcept{input_or_output_iterator}@ I> - constexpr I next(I x, iter_difference_t n); // freestanding + constexpr I next(I x, iter_difference_t n); template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr I next(I x, S bound); // freestanding + constexpr I next(I x, S bound); template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr I next(I x, iter_difference_t n, S bound); // freestanding + constexpr I next(I x, iter_difference_t n, S bound); // \ref{range.iter.op.prev}, \tcode{ranges::prev} template<@\libconcept{bidirectional_iterator}@ I> - constexpr I prev(I x); // freestanding + constexpr I prev(I x); template<@\libconcept{bidirectional_iterator}@ I> - constexpr I prev(I x, iter_difference_t n); // freestanding + constexpr I prev(I x, iter_difference_t n); template<@\libconcept{bidirectional_iterator}@ I> - constexpr I prev(I x, iter_difference_t n, I bound); // freestanding + constexpr I prev(I x, iter_difference_t n, I bound); } // \ref{predef.iterators}, predefined iterators and sentinels // \ref{reverse.iterators}, reverse iterators - template class reverse_iterator; // freestanding + template class reverse_iterator; template - constexpr bool operator==( // freestanding + constexpr bool operator==( const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator!=( // freestanding + constexpr bool operator!=( const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator<( // freestanding + constexpr bool operator<( const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator>( // freestanding + constexpr bool operator>( const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator<=( // freestanding + constexpr bool operator<=( const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator>=( // freestanding + constexpr bool operator>=( const reverse_iterator& x, const reverse_iterator& y); template Iterator2> constexpr compare_three_way_result_t - operator<=>(const reverse_iterator& x, // freestanding + operator<=>(const reverse_iterator& x, const reverse_iterator& y); template - constexpr auto operator-( // freestanding + constexpr auto operator-( const reverse_iterator& x, const reverse_iterator& y) -> decltype(y.base() - x.base()); template - constexpr reverse_iterator operator+( // freestanding + constexpr reverse_iterator operator+( iter_difference_t n, const reverse_iterator& x); template - constexpr reverse_iterator make_reverse_iterator(Iterator i); // freestanding + constexpr reverse_iterator make_reverse_iterator(Iterator i); template requires (!@\libconcept{sized_sentinel_for}@) - constexpr bool @\libspec{disable_sized_sentinel_for}{reverse_iterator}@, // freestanding + constexpr bool @\libspec{disable_sized_sentinel_for}{reverse_iterator}@, reverse_iterator> = true; // \ref{insert.iterators}, insert iterators - template class back_insert_iterator; // freestanding + template class back_insert_iterator; template - constexpr back_insert_iterator back_inserter(Container& x); // freestanding + constexpr back_insert_iterator back_inserter(Container& x); - template class front_insert_iterator; // freestanding + template class front_insert_iterator; template - constexpr front_insert_iterator front_inserter(Container& x); // freestanding + constexpr front_insert_iterator front_inserter(Container& x); - template class insert_iterator; // freestanding + template class insert_iterator; template constexpr insert_iterator - inserter(Container& x, ranges::iterator_t i); // freestanding + inserter(Container& x, ranges::iterator_t i); // \ref{const.iterators}, constant iterators and sentinels // \ref{const.iterators.alias}, alias templates template<@\libconcept{indirectly_readable}@ I> - using iter_const_reference_t = @\seebelow@; // freestanding + using iter_const_reference_t = @\seebelow@; template concept @\exposconcept{constant-iterator}@ = @\seebelow@; // \expos template<@\libconcept{input_iterator}@ I> - using const_iterator = @\seebelow@; // freestanding + using const_iterator = @\seebelow@; template<@\libconcept{semiregular}@ S> - using const_sentinel = @\seebelow@; // freestanding + using const_sentinel = @\seebelow@; // \ref{const.iterators.iterator}, class template \tcode{basic_const_iterator} template<@\libconcept{input_iterator}@ Iterator> - class basic_const_iterator; // freestanding + class basic_const_iterator; template U> requires @\libconcept{input_iterator}@> - struct common_type, U> { // freestanding + struct common_type, U> { using type = basic_const_iterator>; }; template U> requires @\libconcept{input_iterator}@> - struct common_type> { // freestanding + struct common_type> { using type = basic_const_iterator>; }; template U> requires @\libconcept{input_iterator}@> - struct common_type, basic_const_iterator> { // freestanding + struct common_type, basic_const_iterator> { using type = basic_const_iterator>; }; template<@\libconcept{input_iterator}@ I> - constexpr const_iterator @\libglobal{make_const_iterator}@(I it) { return it; } // freestanding + constexpr const_iterator @\libglobal{make_const_iterator}@(I it) { return it; } template<@\libconcept{semiregular}@ S> - constexpr const_sentinel @\libglobal{make_const_sentinel}@(S s) { return s; } // freestanding + constexpr const_sentinel @\libglobal{make_const_sentinel}@(S s) { return s; } // \ref{move.iterators}, move iterators and sentinels - template class move_iterator; // freestanding + template class move_iterator; template - constexpr bool operator==( // freestanding + constexpr bool operator==( const move_iterator& x, const move_iterator& y); template - constexpr bool operator<( // freestanding + constexpr bool operator<( const move_iterator& x, const move_iterator& y); template - constexpr bool operator>( // freestanding + constexpr bool operator>( const move_iterator& x, const move_iterator& y); template - constexpr bool operator<=( // freestanding + constexpr bool operator<=( const move_iterator& x, const move_iterator& y); template - constexpr bool operator>=( // freestanding + constexpr bool operator>=( const move_iterator& x, const move_iterator& y); template Iterator2> constexpr compare_three_way_result_t - operator<=>(const move_iterator& x, // freestanding + operator<=>(const move_iterator& x, const move_iterator& y); template - constexpr auto operator-( // freestanding + constexpr auto operator-( const move_iterator& x, const move_iterator& y) -> decltype(x.base() - y.base()); template constexpr move_iterator - operator+(iter_difference_t n, const move_iterator& x); // freestanding + operator+(iter_difference_t n, const move_iterator& x); template - constexpr move_iterator make_move_iterator(Iterator i); // freestanding + constexpr move_iterator make_move_iterator(Iterator i); template requires (!@\libconcept{sized_sentinel_for}@) - constexpr bool @\libspec{disable_sized_sentinel_for}{move_iterator}@, // freestanding + constexpr bool @\libspec{disable_sized_sentinel_for}{move_iterator}@, move_iterator> = true; - template<@\libconcept{semiregular}@ S> class move_sentinel; // freestanding + template<@\libconcept{semiregular}@ S> class move_sentinel; // \ref{iterators.common}, common iterators template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> requires (!@\libconcept{same_as}@ && @\libconcept{copyable}@) - class common_iterator; // freestanding + class common_iterator; template - struct incrementable_traits>; // freestanding + struct incrementable_traits>; template<@\libconcept{input_iterator}@ I, class S> - struct iterator_traits>; // freestanding + struct iterator_traits>; // \ref{default.sentinel}, default sentinel - struct default_sentinel_t; // freestanding - inline constexpr default_sentinel_t @\libglobal{default_sentinel}@{}; // freestanding + struct default_sentinel_t; + inline constexpr default_sentinel_t @\libglobal{default_sentinel}@{}; // \ref{iterators.counted}, counted iterators - template<@\libconcept{input_or_output_iterator}@ I> class counted_iterator; // freestanding + template<@\libconcept{input_or_output_iterator}@ I> class counted_iterator; template<@\libconcept{input_iterator}@ I> requires @\seebelow@ - struct iterator_traits>; // freestanding + struct iterator_traits>; // \ref{unreachable.sentinel}, unreachable sentinel - struct unreachable_sentinel_t; // freestanding - inline constexpr unreachable_sentinel_t @\libglobal{unreachable_sentinel}@{}; // freestanding + struct unreachable_sentinel_t; + inline constexpr unreachable_sentinel_t @\libglobal{unreachable_sentinel}@{}; // \ref{stream.iterators}, stream iterators template, class Distance = ptrdiff_t> - class istream_iterator; + class istream_iterator; // hosted template - bool operator==(const istream_iterator& x, + bool operator==(const istream_iterator& x, // hosted const istream_iterator& y); template> - class ostream_iterator; + class ostream_iterator; // hosted template> - class istreambuf_iterator; + class istreambuf_iterator; // hosted template - bool operator==(const istreambuf_iterator& a, + bool operator==(const istreambuf_iterator& a, // hosted const istreambuf_iterator& b); template> - class ostreambuf_iterator; + class ostreambuf_iterator; // hosted // \ref{iterator.range}, range access template constexpr auto - begin(C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); // freestanding + begin(C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); template constexpr auto - begin(const C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); // freestanding + begin(const C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); template constexpr auto - end(C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); // freestanding + end(C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); template constexpr auto - end(const C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); // freestanding - template constexpr T* begin(T (&array)[N]) noexcept; // freestanding - template constexpr T* end(T (&array)[N]) noexcept; // freestanding + end(const C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); + template constexpr T* begin(T (&array)[N]) noexcept; + template constexpr T* end(T (&array)[N]) noexcept; template constexpr auto - cbegin(const C& c) noexcept(noexcept(std::begin(c))) - -> decltype(std::begin(c)); // freestanding + cbegin(const C& c) noexcept(noexcept(std::begin(c))) -> decltype(std::begin(c)); template constexpr auto - cend(const C& c) noexcept(noexcept(std::end(c))) -> decltype(std::end(c)); // freestanding + cend(const C& c) noexcept(noexcept(std::end(c))) -> decltype(std::end(c)); template constexpr auto - rbegin(C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); // freestanding + rbegin(C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); template constexpr auto - rbegin(const C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); // freestanding + rbegin(const C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); template constexpr auto - rend(C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); // freestanding + rend(C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); template constexpr auto - rend(const C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); // freestanding + rend(const C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); template constexpr reverse_iterator - rbegin(T (&array)[N]) noexcept; // freestanding + rbegin(T (&array)[N]) noexcept; template constexpr reverse_iterator - rend(T (&array)[N]) noexcept; // freestanding + rend(T (&array)[N]) noexcept; template constexpr reverse_iterator - rbegin(initializer_list il) noexcept; // freestanding + rbegin(initializer_list il) noexcept; template constexpr reverse_iterator - rend(initializer_list il) noexcept; // freestanding + rend(initializer_list il) noexcept; template constexpr auto - crbegin(const C& c) noexcept(noexcept(std::rbegin(c))) - -> decltype(std::rbegin(c)); // freestanding + crbegin(const C& c) noexcept(noexcept(std::rbegin(c))) -> decltype(std::rbegin(c)); template constexpr auto - crend(const C& c) noexcept(noexcept(std::rend(c))) -> decltype(std::rend(c)); // freestanding + crend(const C& c) noexcept(noexcept(std::rend(c))) -> decltype(std::rend(c)); template constexpr auto - size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size()); // freestanding + size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size()); template constexpr size_t - size(const T (&array)[N]) noexcept; // freestanding + size(const T (&array)[N]) noexcept; template constexpr auto ssize(const C& c) noexcept(noexcept(c.size())) - -> common_type_t>; // freestanding + -> common_type_t>; template constexpr ptrdiff_t - ssize(const T (&array)[N]) noexcept; // freestanding + ssize(const T (&array)[N]) noexcept; template constexpr auto - empty(const C& c) noexcept(noexcept(c.empty())) -> decltype(c.empty()); // freestanding + empty(const C& c) noexcept(noexcept(c.empty())) -> decltype(c.empty()); template constexpr bool - empty(const T (&array)[N]) noexcept; // freestanding + empty(const T (&array)[N]) noexcept; template constexpr auto - data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); // freestanding + data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); template constexpr auto - data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); // freestanding - template constexpr T* data(T (&array)[N]) noexcept; // freestanding + data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); + template constexpr T* data(T (&array)[N]) noexcept; } \end{codeblock}