23 General utilities library [utilities]

23.2 Utility components [utility]

Этот подпункт содержит некоторые базовые шаблоны функций и классов, которые используются во всей остальной части библиотеки.

23.2.1 Header <utility> synopsis [utility.syn]

#include <initializer_list>     // see [initializer_list.syn]

namespace std {
  // [operators], operators
  namespace rel_ops {
    template<class T> bool operator!=(const T&, const T&);
    template<class T> bool operator> (const T&, const T&);
    template<class T> bool operator<=(const T&, const T&);
    template<class T> bool operator>=(const T&, const T&);
  }

  // [utility.swap], swap
  template <class T>
    void swap(T& a, T& b) noexcept(see below);
  template <class T, size_t N>
    void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);

  // [utility.exchange], exchange
  template <class T, class U = T>
    T exchange(T& obj, U&& new_val);

  // [forward], forward/move
  template <class T>
    constexpr T&& forward(remove_reference_t<T>& t) noexcept;
  template <class T>
    constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
  template <class T>
    constexpr remove_reference_t<T>&& move(T&&) noexcept;
  template <class T>
    constexpr conditional_t<
        !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&>
      move_if_noexcept(T& x) noexcept;

  // [utility.as_const], as_­const
  template <class T>
    constexpr add_const_t<T>& as_const(T& t) noexcept;
  template <class T>
    void as_const(const T&&) = delete;

  // [declval], declval
  template <class T>
    add_rvalue_reference_t<T> declval() noexcept;  // as unevaluated operand

  // [intseq], Compile-time integer sequences
  template<class T, T...>
    struct integer_sequence;
  template<size_t... I>
    using index_sequence = integer_sequence<size_t, I...>;

  template<class T, T N>
    using make_integer_sequence = integer_sequence<T, see below>;
  template<size_t N>
    using make_index_sequence = make_integer_sequence<size_t, N>;

  template<class... T>
    using index_sequence_for = make_index_sequence<sizeof...(T)>;

  // [pairs], class template pair
  template <class T1, class T2>
    struct pair;

  // [pairs.spec], pair specialized algorithms
  template <class T1, class T2>
    constexpr bool operator==(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator< (const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator!=(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator> (const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator>=(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator<=(const pair<T1, T2>&, const pair<T1, T2>&);

  template <class T1, class T2>
    void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));

  template <class T1, class T2>
    constexpr see below make_pair(T1&&, T2&&);

  // [pair.astuple], tuple-like access to pair
  template <class T> class tuple_size;
  template <size_t I, class T> class tuple_element;

  template <class T1, class T2> struct tuple_size<pair<T1, T2>>;
  template <class T1, class T2> struct tuple_element<0, pair<T1, T2>>;
  template <class T1, class T2> struct tuple_element<1, pair<T1, T2>>;

  template<size_t I, class T1, class T2>
    constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&&) noexcept;
  template <class T1, class T2>
    constexpr T1& get(pair<T1, T2>& p) noexcept;
  template <class T1, class T2>
    constexpr const T1& get(const pair<T1, T2>& p) noexcept;
  template <class T1, class T2>
    constexpr T1&& get(pair<T1, T2>&& p) noexcept;
  template <class T1, class T2>
    constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
  template <class T2, class T1>
    constexpr T2& get(pair<T1, T2>& p) noexcept;
  template <class T2, class T1>
    constexpr const T2& get(const pair<T1, T2>& p) noexcept;
  template <class T2, class T1>
    constexpr T2&& get(pair<T1, T2>&& p) noexcept;
  template <class T2, class T1>
    constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;

  // [pair.piecewise], pair piecewise construction
  struct piecewise_construct_t {
    explicit piecewise_construct_t() = default;
  };
  inline constexpr piecewise_construct_t piecewise_construct{};
  template <class... Types> class tuple;        // defined in <tuple>

  // in-place construction
  struct in_place_t {
    explicit in_place_t() = default;
  };
  inline constexpr in_place_t in_place{};
  template <class T>
    struct in_place_type_t {
      explicit in_place_type_t() = default;
    };
  template <class T> inline constexpr in_place_type_t<T> in_place_type{};
  template <size_t I>
    struct in_place_index_t {
      explicit in_place_index_t() = default;
    };
  template <size_t I> inline constexpr in_place_index_t<I> in_place_index{};

  // floating-point format for primitive numerical conversion
  enum class chars_­format {
    scientific = unspecified,
    fixed = unspecified,
    hex = unspecified,
    general = fixed | scientific
  };



  // [utility.to.chars], primitive numerical output conversion
  struct to_chars_result {
    char* ptr;
    error_code ec;
  };

  to_chars_result to_chars(char* first, char* last, see below value, int base = 10);

  to_chars_result to_chars(char* first, char* last, float value);
  to_chars_result to_chars(char* first, char* last, double value);
  to_chars_result to_chars(char* first, char* last, long double value);

  to_chars_result to_chars(char* first, char* last, float value,
                           chars_format fmt);
  to_chars_result to_chars(char* first, char* last, double value,
                           chars_format fmt);
  to_chars_result to_chars(char* first, char* last, long double value,
                           chars_format fmt);

  to_chars_result to_chars(char* first, char* last, float value,
                           chars_format fmt, int precision);
  to_chars_result to_chars(char* first, char* last, double value,
                           chars_format fmt, int precision);
  to_chars_result to_chars(char* first, char* last, long double value,
                           chars_format fmt, int precision);



  // [utility.from.chars], primitive numerical input conversion
  struct from_chars_result {
    const char* ptr;
    error_code ec;
  };

  from_chars_result from_chars(const char* first, const char* last,
                               see below& value, int base = 10);

  from_chars_result from_chars(const char* first, const char* last, float& value,
                               chars_format fmt = chars_format::general);
  from_chars_result from_chars(const char* first, const char* last, double& value,
                               chars_format fmt = chars_format::general);
  from_chars_result from_chars(const char* first, const char* last, long double& value,
                               chars_format fmt = chars_format::general);
}

Заголовок<utility> определяет несколько типов и шаблонов функций, которые описаны в этом разделе. Он также определяет шаблонpair и различные шаблоны функций, которые работают сpair объектами.

Типаchars_­format являетсяbitmask type с элементами scientific, fixedиhex.

23.2.2 Operators [operators]

Чтобы избежать лишних определенийoperator!= отказа отoperator== и операторов>,<=и>= изoperator<, библиотека предоставляет следующее:

template <class T> bool operator!=(const T& x, const T& y);

Requires: ТипаT естьEqualityComparable.

Returns: !(x == y).

template <class T> bool operator>(const T& x, const T& y);

Requires: ТипаT естьLessThanComparable.

Returns: y < x.

template <class T> bool operator<=(const T& x, const T& y);

Requires: ТипаT естьLessThanComparable.

Returns: !(y < x).

template <class T> bool operator>=(const T& x, const T& y);

Requires: ТипаT естьLessThanComparable.

Returns: !(x < y).

В этой библиотеке, когда декларация предоставляется заoperator!=, operator>,operator>=илиoperator<=, а также требования и семантика явно не предусмотрено, требования и семантика , как указано в настоящем пункте.

23.2.3 swap [utility.swap]

template <class T> void swap(T& a, T& b) noexcept(see below);

Remarks: Эта функция не будет участвовать в разрешении перегрузки , еслиis_­move_­constructible_­v<T> неtrue и is_­move_­assignable_­v<T> являетсяtrue. Выражение внутриnoexcept эквивалентно:

is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>

Requires: Тип T должен быть MoveConstructible и MoveAssignable.

Effects: Обмен ценностями, хранящимися в двух местах.

template <class T, size_t N> void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);

Remarks: Эта функция не будет участвовать в разрешении перегрузки , еслиis_­swappable_­v<T> неtrue.

Requires: a[i] должен бытьswappable withb[i] у всехi в ассортименте[0, N).

Effects: Как будто мимоswap_­ranges(a, a + N, b).

23.2.4 exchange [utility.exchange]

template <class T, class U = T> T exchange(T& obj, U&& new_val);

Effects: Эквивалентен:

T old_val = std::move(obj);
obj = std::forward<U>(new_val);
return old_val;

23.2.5 Forward/move helpers [forward]

Библиотека предоставляет шаблонные вспомогательные функции, чтобы упростить применение семантики перемещения к lvalue и упростить реализацию функций пересылки. Все функции, указанные в этом подпункте, являются signal-safe ( ).[csignal.syn]

template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;

Returns:static_­cast<T&&>(t).

Remarks: Если вторая форма создается со ссылочным типом lvalue, программа имеет неправильный формат.

[Example:

template <class T, class A1, class A2>
shared_ptr<T> factory(A1&& a1, A2&& a2) {
  return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2)));
}

struct A {
  A(int&, const double&);
};

void g() {
  shared_ptr<A> sp1 = factory<A>(2, 1.414); // error: 2 will not bind to int&
  int i = 2;
  shared_ptr<A> sp2 = factory<A>(i, 1.414); // OK
}

При первом вызовеfactory, A1 выводится какint, поэтому 2 передаетсяAконструктору как rvalue. Во втором вызовеfactory, A1 выводится какint&, поэтомуi передаетсяAконструктору как lvalue. В обоих случаяхA2 выводится какdouble, поэтому 1.414 передаетсяAконструктору как rvalue. ] end example

template <class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;

Returns: static_­cast<remove_­reference_­t<T>&&>(t).

[Example:

template <class T, class A1>
shared_ptr<T> factory(A1&& a1) {
  return shared_ptr<T>(new T(std::forward<A1>(a1)));
}

struct A {
  A();
  A(const A&);      // copies from lvalues
  A(A&&);           // moves from rvalues
};

void g() {
  A a;
  shared_ptr<A> sp1 = factory<A>(a);                // “a” binds to A(const A&)
  shared_ptr<A> sp1 = factory<A>(std::move(a));     // “a” binds to A(A&&)
}

При первом вызовеfactory, A1 выводится какA&, поэтомуa передается как неконстантное lvalue. Это связывается с конструкторомA(const A&), который копирует значение изa. Во втором вызовеfactory, из - за вызова std​::​move(a), A1 выводится в видеA, такa пересылается как RValue. Это связывается с конструкторомA(A&&), который перемещает значение изa. ] end example

template <class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept;

Returns:std​::​move(x).

23.2.6 Function template as_­const [utility.as_const]

template <class T> constexpr add_const_t<T>& as_const(T& t) noexcept;

Returns:t.

23.2.7 Function template declval [declval]

Библиотека предоставляет шаблон функцииdeclval для упрощения определения выражений, которые встречаются какunevaluated operands.

template <class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand

Remarks: Если эта функция естьodr-used, программа неправильно сформирована.

Remarks: Параметр шаблонаT изdeclval может быть неполным типом.

[Example:

template <class To, class From> decltype(static_cast<To>(declval<From>())) convert(From&&);

объявляет шаблон функции,convert который участвует в перегрузке только в том случае, если типFrom может быть явно преобразован в типTo. Другой пример см. В шаблоне классаcommon_­type ([meta.trans.other]). ]end example

23.2.8 Primitive numeric output conversion [utility.to.chars]

Все названные функцииto_­chars преобразуютсяvalue в символьную строку, последовательно заполняя диапазон [first, last), где[first, last) должен быть допустимый диапазон. Если членec возвращаемого значения таков , что значение, при преобразованииbool, являетсяfalseпереход был успешным , и членомptr является один пришедшей к конец указатель из записанных символов. В противном случае членec имеет значениеerrc​::​value_­too_­large, членptr имеет значениеlast, а содержимое диапазона[first, last) не указано.

Функции, которые принимают число с плавающей запятой,value но неprecision параметр, гарантируют, что строковое представление состоит из наименьшего количества символов, так что есть хотя бы одна цифра перед точкой счисления (если есть), и анализ представления с использованием соответствующейfrom_­chars функции восстанавливаетvalue точно . [ Note: Эта гарантия применяется, только если to_­chars иfrom_­chars выполняются в одной и той же реализации. ]end note

Функции , принимаяchars_­format параметр определяет спецификатор преобразования дляprintf следующим образом : спецификатор преобразования ,f еслиfmt этоchars_­format​::​fixed, e еслиfmt этоchars_­format​::​scientific, a (не приводя"0x" в результате) , еслиfmt этоchars_­format​::​hex, и g еслиfmt этоchars_­format​::​general.

to_chars_result to_chars(char* first, char* last, see below value, int base = 10);

Requires:base имеет значение от 2 до 36 (включительно).

Effects: Значениеvalue преобразуется в строку цифр с заданным основанием (без повторяющихся нулей в начале). Цифры в диапазоне 10..35 (включительно) представлены в виде символов в нижнем регистреa..z. Еслиvalue меньше нуля, представление начинается со знака минус.

Throws: Ничего такого.

Remarks: Реализация должна обеспечивать перегрузки для всех целочисленных типов со знаком и без знака, аchar также для типа параметраvalue.

to_chars_result to_chars(char* first, char* last, float value); to_chars_result to_chars(char* first, char* last, double value); to_chars_result to_chars(char* first, char* last, long double value);

Effects:value преобразуется в строку в стилеprintf в"C" локали. Спецификатор преобразованияf илиe, выбирается в соответствии с потребностью в кратчайшее представление (смотрите выше); ничья разрешается в пользуf.

Throws: Ничего такого.

to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt);

Requires:fmt имеет значение одного из перечислителейchars_­format.

Effects:value преобразуется в строку в стилеprintf в"C" локали.

Throws: Ничего такого.

to_chars_result to_chars(char* first, char* last, float value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt, int precision);

Requires:fmt имеет значение одного из перечислителейchars_­format.

Effects:value преобразуются в строку в стилеprintf в"C" местности с заданной точностью.

Throws: Ничего такого.

См. Также: ISO C 7.21.6.1.

23.2.9 Primitive numeric input conversion [utility.from.chars]

Все названные функцииfrom_­chars анализируют строку на[first, last) предмет шаблона, где[first, last) должен быть допустимый диапазон. Если ни один символ не соответствует шаблону, value не изменяется, членptr возвращаемого значения равен,first а членec равенerrc​::​invalid_­argument. В противном случае символы, соответствующие шаблону, интерпретируются как представление значения типаvalue. Членptr возвращаемого значения указывает на первый символ, не соответствующий шаблону, или имеет значение,last если все символы совпадают. Если проанализированное значение не находится в диапазоне, представленном типомvalue, value не изменяется и членec возвращаемого значения равенerrc​::​result_­out_­of_­range. В противном случае value устанавливается проанализированное значение, а членec устанавливается таким образом, что преобразование вbool даетfalse.

from_chars_result from_chars(const char* first, const char* last, see below& value, int base = 10);

Requires:base имеет значение от 2 до 36 (включительно).

Effects: Шаблон - это ожидаемая форма субъектной последовательности в"C" локали для данной ненулевой базы, как описано дляstrtol, за исключением того, что префикс"0x" или не"0X" должен отображаться, если значениеbase равно 16, и за исключением того, что знак минус является единственным знаком, который может появиться , и только еслиvalue имеет подписанный тип.

Throws: Ничего такого.

Remarks: Реализация должна обеспечивать перегрузки для всех целочисленных типов со знаком и без знака, а такжеchar в качестве ссылочного типа параметраvalue.

from_chars_result from_chars(const char* first, const char* last, float& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, double& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, long double& value, chars_format fmt = chars_format::general);

Requires:fmt имеет значение одного из перечислителейchars_­format.

Effects: Шаблон - это ожидаемая форма предметной последовательности в"C" локали, как описано дляstrtod, за исключением того, что

  • единственный знак, который может появиться, - это знак минус;

  • еслиfmt ужеchars_­format​::​scientific установлено , но неchars_­format​::​fixed, то в противном случае обязательной часть экспонентов проставляется;

  • еслиfmt естьchars_­format​::​fixed набор , но неchars_­format​::​scientific, дополнительный показатель часть не должна появляться; а также

  • еслиfmt естьchars_­format​::​hex, то предполагается префикс"0x" или"0X" . [ Example: Строка0x123 анализируется, чтобы получить значение 0 с оставшимися символамиx123. ] end example

В любом случае результатомvalue является одно из максимум двух значений с плавающей запятой, ближайших к значению строки, соответствующей шаблону.

Throws: Ничего такого.

См. Также: ISO C 7.22.1.3, ISO C 7.22.1.4.