Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::ranges::to(3)	      C++ Standard Libary	    std::ranges::to(3)

NAME
       std::ranges::to - std::ranges::to

Synopsis
	  Defined in header <ranges>
	  template< class C, ranges::input_range R, class... Args >

	      requires					    (!ranges::view<C>)
       (1) (since C++23)

	  constexpr C to( R&& r, Args&&... args	);
	  template< template< class... > class C, ranges::input_range R,
	  class...			     Args			     >
       (2) (since C++23)
	  constexpr auto to( R&& r, Args&&... args );
	  template< class C, class... Args >

	      requires					    (!ranges::view<C>)
       (3) (since C++23)

	  constexpr /*range adaptor closure*/ to( Args&&... args );
	  template<  template<	class...  >   class   C,   class...   Args   >
       (4) (since C++23)
	  constexpr /*range adaptor closure*/ to( Args&&... args );
	  Helper templates
	  template< class Container >

	  constexpr bool /*reservable-container*/ =
	      ranges::sized_range<Container> &&
	      requires	 (Container&   c,  ranges::range_size_t<Container>  n)
       (exposition
	      {
       (5) only*)
		  c.reserve(n);
		  { c.capacity() } -> std::same_as<decltype(n)>;
		  { c.max_size() } -> std::same_as<decltype(n)>;

	      };
	  template< class Container, class Reference >

	  constexpr bool /*container-appendable*/ = requires (Container& c,
	  Reference&& ref)
	  {
	      requires (requires {
	  c.emplace_back(std::forward<Reference>(ref));	       }	    ||
       (exposition
			requires					     {
       (6) only*)
	  c.push_back(std::forward<Reference>(ref)); }	     ||
			requires { c.emplace(c.end(),
	  std::forward<Reference>(ref);	} ||
			requires { c.insert(c.end(),
	  std::forward<Reference>(ref)); });

	  };
	  template< class Reference, class C >

	  constexpr auto /*container-appender*/( C& c )
	  {
	      return [&c]<class	Reference>(Reference&& ref)
	      {
		  if constexpr (requires {
	  c.emplace_back(std::declval<Reference>()); })
		      c.emplace_back(std::forward<Reference>(ref));
		  else	      if	 constexpr	   (requires	     {
       (exposition
	  c.push_back(std::declval<Reference>());			    })
       (7) only*)
		      c.push_back(std::forward<Reference>(ref));
		  else if constexpr (requires {	c.emplace(c.end(),

	  std::declval<Reference>()); })
		      c.emplace(c.end(), std::forward<Reference>(ref));
		  else
		      c.insert(c.end(),	std::forward<Reference>(ref));
	      };

	  }
	  template< class R, class T >

	  concept		/*container-compatible-range*/		     =
       (8) (exposition
	      ranges::input_range<R>					    &&
       only*)

	      std::convertible_to<ranges::range_reference_t<R>,	T>;

	  The overloads	of the range conversion	function construct a new  non-
       view object from
	  a source range as its	first argument by calling a constructor	taking
       a range,	a
	  std::from_range_t tagged ranged constructor, a constructor taking an
	  iterator-sentinel  pair,  or	by  back inserting each	element	of the
       source range into
	  the arguments-constructed object.

	  1) Constructs	an object of type C from the elements of r in the fol-
       lowing:
	  a) If	C does not satisfy input_range or
	  std::convertible_to<ranges::range_reference_t<R>,
       ranges::range_value_t<C>> is true:
	  1) Constructing a non-view object as if direct-initializing (but not
	  direct-list-initializing) an object of type C	from the source	range
	  std::forward<R>(r) and the rest of the functional arguments
	  std::forward<Args>(args)...	if    std::constructible_from<C,    R,
       Args...>	is true.
	  2) Otherwise,	constructing a non-view	object as if direct-initializ-
       ing (but	not
	  direct-list-initializing) an object of type C	from additional	disam-
       biguation tag
	  std::from_range, the source range std::forward<R>(r) and the rest of
       the functional
	  arguments std::forward<Args>(args)...	if std::constructible_from<C,
	  std::from_range_t, R,	Args...> is true.
	  3) Otherwise,	constructing a non-view	object as if direct-initializ-
       ing (but	not
	  direct-list-initializing) an object of type C	from the iterator-sen-
       tinel pair
	  (ranges::begin(r)  as	 an  iterator  and ranges::end(r) as sentinel,
       where iterator and
	  sentinel have	the same type. In other	words, the source  range  must
       be a common
	  range),    and    the	  rest	 of   function	 arguments   std::for-
       ward<Args>(args)... if all of the
	  conditions below are true:
	    * ranges::common_range<R>
	    *  If  std::iterator_traits<ranges::iterator_t<R>>::iterator_cate-
       gory is valid and
	      denotes a	type that satisfies std::derived_from<std::input_iter-
       ator_tag>
	    *  std::constructible_from<C,  ranges::iterator_t<R>, ranges::sen-
       tinel_t<R>,
	      Args...>
	  4) Otherwise,	constructing a non-view	range object as	if direct-ini-
       tializing (but
	  not direct-list-initializing)	an object of type C from the  rest  of
       the function
	  arguments  std::forward<Args>(args)... with the following equivalent
       call below after
	  the construction:

	  if constexpr (ranges::sized_range<R> && /*reservable-container*/<C>)
	      c.reserve(sta-
       tic_cast<ranges::range_size_t<C>>(ranges::size(r)));
	  ranges::for_each(r, /*container-appender*/(c));
	  If the R satisfies sized_range  and  C  satisfies  /*reservable-con-
       tainer*/, the
	  constructed  object  c of type C is able to reserve storage with the
       initial storage
	  size ranges::size(r) to prevent additional  allocations  during  in-
       serting new
	  elements.  Each  element of r	is appended to c. The operations above
       are valid if both
	  of the conditions below are true:

	    * std::constructible_from<C, Args...>
	    * /*container-appendable*/<C, ranges::range_reference_t<R>>
	  b) Otherwise,	the return expression is equivalent to:

	  to<C>(ranges::ref_view(r) | views::transform([](auto&& elem)
	  {
	      return		 to<ranges::range_value_t<C>>(std::forward<de-
       cltype(elem)>(elem));
	  }), std::forward<Args>(args)...)
	  Which	allows nested range constructions within the range if
	  ranges::input_range<ranges::range_reference_t<C>> is true.

	  Otherwise, the program is ill-formed.
	  2) Constructs	an object of deduced type from the elements of r.

	  Let /*input-iterator*/ be an exposition only type that satisfies
	  LegacyInputIterator:

	  struct /*input-iterator*/

	  {
	      using iterator_category =	std::input_iterator_tag;
	      using value_type = ranges::range_value_t<R>;
	      using difference_type = std::ptrdiff_t;
	      using pointer =
	  std::add_pointer_t<ranges::range_reference_t<R>>;
	      using reference =	ranges::range_reference_t<R>;
	      reference	operator*() const;			// not
	  defined
       (exposition only*)
	      pointer operator->() const;			// not
	  defined
	      /*input-iterator*/& operator++();			// not
	  defined
	      /*input-iterator*/ operator++(int);		// not
	  defined
	      bool operator==(const /*input-iterator*/&) const;	// not
	  defined

	  };

	  Let /*DEDUCE-EXPR*/ be defined as follows:

	    *  C(std::declval<R>(),  std::declval<Args>()...), if that expres-
       sion is valid.
	    *  Otherwise,   C(std::from_range,	 std::declval<R>(),   std::de-
       clval<Args>()...), if
	      that expression is valid.
	    * Otherwise, C(std::declval</*input-iterator*/>(),
	      std::declval</*input-iterator*/>(), std::declval<Args>()...), if
       that expression
	      is valid.
	    * Otherwise, the program is	ill-formed.
	  The  call  is	 equivalent to to<decltype(/*DEDUCE-EXPR*/)>(std::for-
       ward<R>(r),
	  std::forward<Args>(args)...).
	  3,4) Returns a perfect forwarding call wrapper that is also a
	  RangeAdaptorClosureObject.
	  5)   The   exposition-only   variable	  template   /*reservable-con-
       tainer*/<Container> is true
	  if  it  satisfies  ranges::sized_range and is	eligible to be reserv-
       able.
	  6)  The  exposition-only   variable	template   /*container-append-
       able*/<Container,
	  Reference>  is true if one element of	type Reference can be appended
       to Container
	  through a member function call emplace_back, push_back,  emplace  or
       insert.
	  7)  The exposition-only function template /*container-appender*/ re-
       turns a function
	  object where a call to the returned function object  is  expression-
       equivalent to
	  appending one	element	to a container.
	  8)  The  exposition-only  concept  /*container-compatible-range*/ is
       used in the
	  definition of	containers in constructing  an	input  range  R	 whose
       range reference type
	  must be convertible to T.

Parameters
	  r    - a source range	object
	  args	-  list	 of  the arguments to (1,2) construct a	range or (3,4)
       bind to the last
		 parameters of range adaptor closure object

Type requirements
	  -
	  C must be cv-unqualified class type (1,3)

Return value
	  1,2) A constructed non-view object.
	  3,4) A range adaptor closure object of unspecified  type,  with  the
       following
	  properties:

       ranges::to return type

	  The  return type is derived from ranges::range_adaptor_closure</*re-
       turn-type*/>.

Member objects
	  The returned object behaves as if it has no target  object,  and  an
       std::tuple object
	  tup	constructed  with  std::tuple<std::decay_t<Args>...>(std::for-
       ward<Args>(args)...),
	  except that the returned object's assignment behavior	is unspecified
       and the names
	  are for exposition only.

	   Constructors

	  The return type of ranges::to	(3-4) behaves as if its	copy/move con-
       structors perform
	  a memberwise copy/move. It is	CopyConstructible if all of its	member
       objects
	  (specified above) are	CopyConstructible,  and	 is  MoveConstructible
       otherwise.

Member function	operator()
	  Given	 an object G obtained from an earlier call to range::to</* see
       below
	  */>(args...),	when a glvalue g designating G is invoked in  a	 func-
       tion call
	  expression  g(r), an invocation of the stored	object takes place, as
       if by

	    * ranges::to</* see	below */>(r, std::get<Ns>(g.tup)...), where

	    * r	is a source range object that must satisfy input_range.
	    * Ns is an integer pack 0, 1, ..., (sizeof...(Args)	- 1).
	    * g	is an lvalue in	the call expression if it is an	lvalue in  the
       call expression,
	      and  is  an  rvalue otherwise. Thus std::move(g)(r) can move the
       bound arguments
	      into the call, where g(r)	would copy.
	    * The specified template argument is (3) C or (4) the deduced type
       from a class
	      template C that must not satisfy view.

	  The program is ill-formed if g has volatile-qualified	type.

Exceptions
	  Only throws if construction of a non-view object throws.

Notes
	  The insertion	of elements into the container may involve copy	 which
       can be less
	  efficient  than  move	 because lvalue	references are produced	during
       the indirection
	  call.	Users can opt-in to use	views::as_rvalue to adapt the range in
       order for their
	  elements to always produce an	rvalue reference during	 the  indirec-
       tion call which
	  implies move.

	  The parentheses are mandatory	when using the pipe syntax.

	auto vec = r | std::ranges::to<std::vector>;   // error
	auto vec = r | std::ranges::to<std::vector>(); // OK

	       Feature-test macro	 Value	  Std	    Feature
	  __cpp_lib_ranges_to_container	202202L	(C++23)	std::ranges::to

Example
	  A preview link: Compiler Explorer

       // Run this code

	#include <concepts>
	#include <list>
	#include <print>
	#include <ranges>
	#include <vector>

	int main()
	{
	    auto vec = std::views::iota(1, 5)
		     |	std::views::transform([](auto  const v){ return	v * 2;
       })
		     | std::ranges::to<std::vector>();

	    static_assert(std::same_as<decltype(vec), std::vector<int>>);
	    std::println("{}", vec);

	    auto     lst     =	    vec	     |	    std::views::take(3)	     |
       std::ranges::to<std::list<double>>();
	    std::println("{}", lst);
	}

Output:
	[2, 4, 6, 8]
	[2, 4, 6]

References
	    * C++23 standard (ISO/IEC 14882:2023):

	    * 26.5.7 Range conversions [range.utility.conv]

	  Defect reports

	  The following	behavior-changing defect reports were applied retroac-
       tively to
	  previously published C++ standards.

	     DR	    Applied to	       Behavior	as published		  Cor-
       rect behavior
			      the nested construction branch of
	  LWG  3984  C++23	 ranges::to				  made
       well-formed
			      resulted to program ill-formed if	R&
			      does not model viewable_range
			      the  container insertion branch of      replaced
       with direct
	  LWG 4016 C++23      ranges::to involved use of	     appending
			      insert iterators			      of  ele-
       ments to	container

http://cppreference.com		  2024.06.10		    std::ranges::to(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::ranges::to&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help