Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Boost.Hana: Functional

Boost , ,

Boost.Hana  1.0.1
Your standard library for metaprogramming
Функциональные объекты общего назначения.

Variables

constexpr auto boost::hana::always
 Return a constant function returning x regardless of the argument(s) it is invoked with. More...
 
constexpr auto boost::hana::apply
 Invokes a Callable with the given arguments. More...
 
template<std::size_t n>
constexpr auto boost::hana::arg
 Return the nth passed argument. More...
 
constexpr auto boost::hana::capture
 Create a function capturing the given variables. More...
 
constexpr auto boost::hana::compose
 Return the composition of two functions or more. More...
 
template<std::size_t n>
constexpr auto boost::hana::curry
 Curry a function up to the given number of arguments. More...
 
constexpr auto boost::hana::demux
 Invoke a function with the results of invoking other functions on its arguments. More...
 
constexpr auto boost::hana::fix
 Return a function computing the fixed point of a function. More...
 
constexpr auto boost::hana::flip
 Invoke a function with its two first arguments reversed. More...
 
constexpr auto boost::hana::id
 The identity function – returns its argument unchanged. More...
 
constexpr auto boost::hana::infix
 Return an equivalent function that can also be applied in infix notation. More...
 
template<std::size_t n>
constexpr auto boost::hana::iterate
 Applies another function n times to its argument. More...
 
constexpr auto boost::hana::lockstep
 Invoke a function with the result of invoking other functions on its arguments, in lockstep. More...
 
constexpr auto boost::hana::on
 Invoke a function with the result of invoking another function on each argument. More...
 
constexpr auto boost::hana::overload
 Pick one of several functions to call based on overload resolution. More...
 
constexpr auto boost::hana::overload_linearly
 Call the first function that produces a valid call expression. More...
 
constexpr auto boost::hana::partial
 Partially apply a function to some arguments. More...
 
constexpr unspecified boost::hana::_ {}
 Create simple functions representing C++ operators inline. More...
 
constexpr auto boost::hana::reverse_partial
 Partially apply a function to some arguments. More...
 

Variable Documentation

constexpr auto boost::hana::always

<#include <boost/hana/functional/always.hpp>>

Initial value:
= [](auto&& x) {
return [perfect-capture](auto const& ...y) -> decltype(auto) {
return forwarded(x);
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Возвращение постоянной функции, возвращающейся<x>независимо от аргумента (аргументов), с которым она вызвана.

<always(x)>является функцией, которая

always(x)(y...) == x

Для всех<y...>. Копия<x>сделана и принадлежит функции<always(x)>. Когда<always(x)>назовут, он вернет ссылку на<x>. Эта ссылка действительна до тех пор, пока<always(x)>находится в объеме.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::always(1)() == 1, "");
static_assert(hana::always('2')(1, 2, 3) == '2', "");
int main() { }
constexpr auto boost::hana::apply

<#include <boost/hana/functional/apply.hpp>>

Initial value:
= [](auto&& f, auto&& ...x) -> decltype(auto) {
return forwarded(f)(forwarded(x)...);
}

Взывает к призыву с приведенными аргументами.

Это эквивалентноstd::invoke, который будет добавлен в C++17. Однако<apply>является функциональным объектом, а не функцией, что позволяет передавать его алгоритмам более высокого порядка.

Parameters
fПризывдля вызова с данными аргументами.
x...Призыв к ответу<f>. Число<x...>должно соответствовать числу<f>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::apply(hana::plus, 1, 2) == 3, "");
int main() { }

Ссылка наboost::hana::literals::operator""_c(), иboost::hana::literals::operator""_s().

template<std::size_t n>
constexpr auto boost::hana::arg

<#include <boost/hana/functional/arg.hpp>>

Initial value:
= [](auto&& x1, ..., auto&& xm) -> decltype(auto) {
return forwarded(xn);
}

Возвратить<n>приведённый довод.

В частности,<arg<n>(x1, ..., xn, ..., xm)>эквивалентно<xn>. Обратите внимание, что индексация начинается с 1, поэтому<arg<1>>возвращает 1-й аргумент,<arg<2>>2-й и так далее.<arg<0>>Ошибка. Недостаток<n>и<arg<n>>также является ошибкой.

Template Parameters
nНеподписанное целое число, представляющее аргумент для возврата.<n>должен быть положительным (то есть ненулевым).
Parameters
x1,...,xmВариадный набор аргументов, из которого<n>один возвращается.

Discussion: could n be dynamic?

Мы могли бы выбрать<arg>для использования<arg(n)(x...)>вместо<arg<n>(x...)>. Если бы все аргументы были одного и того же типа, тогда можно было бы знать<n>только во время выполнения. Однако тогда мы потеряем способность утверждать вложенность<n>статически.

Rationale for n being a non-type template parameter

Я утверждаю, что единственный интересный случай использования - это время компиляции<n>, что означает, что использование станет<arg(int_<n>)(x...)>, что более громоздко писать, чем<arg<n>(x...)>. Это открыто для обсуждения.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
// hana::arg<0>(1, '2', 3.3); // static assertion (regardless of the number of arguments)
static_assert(hana::arg<1>(1, '2', 3.3) == 1, "");
static_assert(hana::arg<2>(1, '2', 3.3) == '2', "");
static_assert(hana::arg<3>(1, '2', 3.3) == 3.3, "");
// hana::arg<4>(1, '2', 3.3); // static assertion
int main() { }
constexpr auto boost::hana::capture

<#include <boost/hana/functional/capture.hpp>>

Initial value:
= [](auto&& ...variables) {
return [perfect-capture](auto&& f) {
return [perfect-capture](auto&& ...args) -> decltype(auto) {
return forwarded(f)(forwarded(variables)..., forwarded(args)...);
};
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Создать функцию захвата заданных переменных.

Учитывая 0 или более переменных,<capture>создает замыкание, которое может быть использовано для частичного применения функции. Это очень похоже на<partial>, за исключением того, что<capture>позволяет уточнить частично примененную функцию позже. В частности,<capture(vars...)>является функциональным объектом, принимающим функцию<f>и возвращающим<f>, частично примененную к<vars...>. Другими словами,

capture(vars...)(f)(args...) == f(vars..., args...)
Note
The arity of f must match the total number of arguments passed to it, i.e. sizeof...(vars) + sizeof...(args).

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
BOOST_HANA_CONSTEXPR_LAMBDA auto sum = [](auto x, auto y, auto z) {
return x + y + z;
};
}
constexpr auto boost::hana::compose

<#include <boost/hana/functional/compose.hpp>>

Initial value:
= [](auto&& f1, auto&& f2, ..., auto&& fn) {
return [perfect-capture](auto&& x, auto&& ...xs) -> decltype(auto) {
return forwarded(f1)(
forwarded(f2)(
...
forwarded(fn)(forwarded(x))
),
forwarded(xs)...
);
}
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Возвращают состав двух функций или более.

<compose>определяется индуктивно. При наличии более двух функций<compose(f, g, h...)>эквивалентно<compose(f, compose(g, h...))>. При наличии двух функций<compose(f, g)>выполняется такая функция, что

compose(f, g)(x, y...) == f(g(x), y...)

Если вам нужна форма<f(g(x, y...))>, используйте<demux>.

Note
compose is an associative operation; compose(f, compose(g, h)) is equivalent to compose(compose(f, g), h).

Proof of associativity

compose(f, compose(g, h))(x, xs...) == f(compose(g, h)(x), xs...)
== f(g(h(x)), xs...)
compose(compose(f, g), h)(x, xs...) == compose(f, g)(h(x), xs...)
== f(g(h(x)), xs...)

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
BOOST_HANA_CONSTEXPR_LAMBDA auto to_char = [](int x) {
return static_cast<char>(x + 48);
};
BOOST_HANA_CONSTEXPR_LAMBDA auto increment = [](auto x) {
return x + 1;
};
BOOST_HANA_CONSTEXPR_CHECK(hana::compose(to_char, increment)(3) == '4');
}
template<std::size_t n>
constexpr auto boost::hana::curry

<#include <boost/hana/functional/curry.hpp>>

Initial value:
= [](auto&& f) {
return [perfect-capture](auto&& x1) {
return [perfect-capture](auto&& x2) {
...
return [perfect-capture](auto&& xn) -> decltype(auto) {
return forwarded(f)(
forwarded(x1), forwarded(x2), ..., forwarded(xn)
);
};
};
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Карри выполняет функцию до заданного числа аргументов.

Карри— это метод, в котором мы рассматриваем функцию, принимающую несколько аргументов (или, эквивалентно, набор аргументов), и превращаем ее в функцию, которая принимает один аргумент и возвращает функцию для обработки оставшихся аргументов. Чтобы помочь визуализировать, давайте обозначим тип функции<f>, которая принимает аргументы типов<X1, ..., Xn>и возвращает<R>как

(X1, ..., Xn) -> R

Затем карриирование — это процесс принятия<f>и превращения его в эквивалентную функцию (назовем его<g>) типа.

X1 -> (X2 -> (... -> (Xn -> R)))

Это дает нам следующую эквивалентность, где<x1>, ...,<xn>являются объектами типа<X1>, ...,<Xn>соответственно:

f(x1, ..., xn) == g(x1)...(xn)

Карри может быть полезен в нескольких ситуациях, особенно при работе с функциями более высокого порядка.

Эта утилита<curry>является реализацией карри на C++. В частности,<curry<n>(f)>является функцией, которая

curry<n>(f)(x1)...(xn) == f(x1, ..., xn)

Обратите внимание, что<n>должно быть указано явно, потому что существование функций с вариадными аргументами в C++ делает невозможным знать, когда карри должен прекратиться.

В отличие от обычного карри, эта реализация также позволяет вызывать криволинейную функцию с несколькими аргументами одновременно. Таким образом, следующее всегда

curry<n>(f)(x1, ..., xk) == curry<n - k>(f)(x1)...(xk)

Конечно, это требует, чтобы<k>было меньше или равно<n>; неспособность удовлетворить это вызовет статическое утверждение. Этот синтаксис поддерживается, потому что он делает криволинейные функции пригодными для использования там, где ожидаются нормальные функции.

Другое «расширение» заключается в том, что<curry<0>(f)>поддерживается:<curry<0>(f)>является нулевой функцией; в то время как классическое определение карри, кажется, оставляет этот случай неопределенным, поскольку нулевые функции не имеют большого смысла в чисто функциональных языках.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
BOOST_HANA_CONSTEXPR_LAMBDA auto add = [](auto x, auto y, auto z) {
return x + y + z;
};
BOOST_HANA_CONSTEXPR_CHECK(hana::curry<3>(add)(1)(2)(3) == 1 + 2 + 3);
BOOST_HANA_CONSTEXPR_CHECK(hana::curry<3>(add)(1)(2, 3) == hana::curry<3>(add)(1)(2)(3));
BOOST_HANA_CONSTEXPR_CHECK(hana::curry<3>(add)(1, 2, 3) == hana::curry<3>(add)(1)(2)(3));
// curry with a nullary function
BOOST_HANA_CONSTEXPR_LAMBDA auto two = []() {
return 2;
};
BOOST_HANA_CONSTEXPR_CHECK(hana::curry<0>(two)() == two());
}
constexpr auto boost::hana::demux

<#include <boost/hana/functional/demux.hpp>>

Initial value:
= [](auto&& f) {
return [perfect-capture](auto&& ...g) {
return [perfect-capture](auto&& ...x) -> decltype(auto) {
return forwarded(f)(forwarded(g)(x...)...);
};
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Вызов функции с результатами вызова других функций на ее аргументы.

В частности,<demux(f)(g...)>является функцией, которая

demux(f)(g...)(x...) == f(g(x...)...)

Каждый<g>называется со всеми аргументами, а затем<f>называется с результатом каждого<g>. Следовательно, число<f>должно соответствовать числу<g>.

Это называется<demux>из-за расплывчатого сходства между этим устройством и демультиплексором в обработке сигналов.<demux>берет то, что можно рассматривать как продолжение<f>, набор функций для разделения сигнала<g...>и ноль или более аргументов, представляющих сигнал<x...>. Затем он вызывает продолжение с результатом расщепления сигнала с какими бы функциями он ни выполнялся.

Note
When used with two functions only, demux is associative. In other words (and noting demux(f, g) = demux(f)(g) to ease the notation), it is true that demux(demux(f, g), h) == demux(f, demux(g, h)).

Signature

<demux>Подпись

\[ \mathtt{demux} : (B_1 \times \dotsb \times B_n \to C) \to ((A_1 \times \dotsb \times A_n \to B_1) \times \dotsb \times (A_1 \times \dotsb \times A_n \to B_n)) \to (A_1 \times \dotsb \times A_n \to C) \]

Его можно переписать более подробно, как

\[ \mathtt{demux} : \left(\prod_{i=1}^n B_i \to C \right) \to \prod_{j=1}^n \left(\prod_{i=1}^n A_i \to B_j \right) \to \left(\prod_{i=1}^n A_i \to C \right) \]

Link with normal composition

Подпись<compose>

\[ \mathtt{compose} : (B \to C) \times (A \to B) \to (A \to C) \]

Достоверным наблюдением является то, что это точно совпадает с типом<demux>при использовании с одной унарной функцией. На самом деле обе функции эквивалентны:

demux(f)(g)(x) == compose(f, g)(x)

Однако, давайте теперь рассмотрим изогнутую версию<compose>,<curry<2>(compose)>:

\[ \mathtt{curry_2(compose)} : (B \to C) \to ((A \to B) \to (A \to C)) \]

Для остальной части этого объяснения мы просто рассмотрим криволинейную версию<compose>, и поэтому мы будем использовать<compose>вместо<curry<2>(compose)>для облегчения обозначения. С карри, мы можем теперь рассмотреть<compose>применяется к себе:

\[ \mathtt{compose(compose, compose)} : (B \to C) \to (A_1 \to A_2 \to B) \to (A_1 \to A_2 \to C) \]

Если мы глубоко отбросим вышеприведенное выражение, мы получим

\[ \mathtt{compose(compose, compose)} : (B \to C) \times (A_1 \times A_2 \to B) \to (A_1 \times A_2 \to C) \]

Эта подпись точно такая же, как и у<demux>, когда задана одна двоичная функция, и действительно они являются эквивалентными определениями. Мы также можем обобщить это, рассмотрев<compose(compose(compose, compose), compose)>:

\[ \mathtt{compose(compose(compose, compose), compose)} : (B \to C) \to (A_1 \to A_2 \to A_3 \to B) \to (A_1 \to A_2 \to A_3 \to C) \]

Который не вступает в

\[ \mathtt{compose(compose(compose, compose), compose)} : (B \to C) \times (A_1 \times A_2 \times A_3 \to B) \to (A_1 \times A_2 \times A_3 \to C) \]

Эта подпись точно такая же, как и у<demux>, когда дана одна троичная функция. Следовательно, для одной функции n-ary<g>,<demux(f)(g)>эквивалентен n-временной композиции<compose>с самим собой, применяемой к<g>и<f>:

demux(f)(g) == fold_left([compose, ..., compose], id, compose)(g, f)
// ^^^^^^^^^^^^^^^^^^^^^ n times

Более подробную информацию об этом можно найти здесь. Кроме того, я не уверен, как это понимание может быть обобщено на более чем одну функцию<g>, или если это вообще возможно.

Proof of associativity in the binary case

107 является ассоциативным, когда используется только с двумя функциями. Действительно, учитывая функции<f>,<g>и<h>с подходящими подписями, мы имеем

demux(f)(demux(g)(h))(x...) == f(demux(g)(h)(x...))
== f(g(h(x...)))

С другой стороны, мы имеем

demux(demux(f)(g))(h)(x...) == demux(f)(g)(h(x...))
== f(g(h(x...)))

<demux>является ассоциативным в двоичном случае.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
using hana::_;
constexpr auto f = hana::demux(hana::make_tuple)(
_ + _,
_ - _,
_ * _,
_ / _
);
static_assert(
f(10, 4) == hana::make_tuple(
10 + 4,
10 - 4,
10 * 4,
10 / 4
)
, "");
int main() { }
constexpr auto boost::hana::fix

<#include <boost/hana/functional/fix.hpp>>

Initial value:
= [](auto&& f) {
return [perfect-capture](auto&& ...x) -> decltype(auto) {
return forwarded(f)(fix(f), forwarded(x)...);
};
}
constexpr auto fix
Возврат функции, вычисляющей фиксированную точку функции.
Definition: fix.hpp:53
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Возврат функции, вычисляющей фиксированную точку функции.

<fix>является реализациейY-комбинатора, также называемого комбинатором с фиксированной точкой. Она кодирует идею рекурсии, и фактически любая рекурсивная функция может быть записана в её терминах.

В частности,<fix(f)>является функцией, которая

fix(f)(x...) == f(fix(f), x...)

Это определение позволяет<f>использовать свой первый аргумент в качестве продолжения, чтобы называть себя рекурсивно. Действительно, если<f>называет свой первый аргумент<y...>, это эквивалентно вызову<f(fix(f), y...)>в соответствии с приведенным выше уравнением.

В большинстве случаев более удобно и эффективно определять рекурсивные функции без использования комбинатора с фиксированной точкой. Однако в некоторых случаях<fix>обеспечивает либо большую гибкость (например, возможность изменения обратного вызова внутри<f>), либо позволяет записывать функции, которые не могут быть определены рекурсивно иначе.

Parameters
fФункция называется<f(self, x...)>, где<x...>являются аргументами в выражении<fix(f)(x...)>и<self>является<fix(f)>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
BOOST_HANA_CONSTEXPR_LAMBDA auto factorial = hana::fix([](auto fact, auto n) -> int {
if (n == 0) return 1;
else return n * fact(n - 1);
});
int main() {
BOOST_HANA_CONSTEXPR_CHECK(factorial(5) == 120);
}
constexpr auto boost::hana::flip

<#include <boost/hana/functional/flip.hpp>>

Initial value:
= [](auto&& f) {
return [perfect-capture](auto&& x, auto&& y, auto&& ...z) -> decltype(auto) {
return forwarded(f)(forwarded(y), forwarded(x), forwarded(z)...);
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Назовите функцию с двумя первыми обратными аргументами.

В частности,<flip(f)>является функцией, которая

flip(f)(x, y, z...) == f(y, x, z...)

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
BOOST_HANA_CONSTEXPR_LAMBDA auto minus = [](int x, int y, int z = 0) {
return x - y - z;
};
int main() {
BOOST_HANA_CONSTEXPR_CHECK(hana::flip(minus)(3, 0) == 0 - 3);
BOOST_HANA_CONSTEXPR_CHECK(minus(3, 0, 1) == 3 - 0 - 1);
BOOST_HANA_CONSTEXPR_CHECK(hana::flip(minus)(3, 0, 1) == 0 - 3 - 1);
}
constexpr auto boost::hana::id

<#include <boost/hana/functional/id.hpp>>

Initial value:
= [](auto&& x) -> decltype(auto) {
return forwarded(x);
}

Функция тождества – возвращает свой аргумент без изменений.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::id(1) == 1, "");
static_assert(hana::id('x') == 'x', "");
int main() { }
constexpr auto boost::hana::infix

<#include <boost/hana/functional/infix.hpp>>

Initial value:
= [](auto f) {
return unspecified;
}

Возврат эквивалентной функции, которая также может быть применена в фиксации.

В частности,<infix(f)>является объектом, который:

infix(f)(x1, ..., xn) == f(x1, ..., xn)
x ^infix(f)^ y == f(x, y)

Следовательно, возвращенная функция все еще может быть применена с использованием обычного синтаксиса вызова функции, но она также получает возможность быть примененной в инфиксной записи. Синтаксис инфикса обеспечивает большую выразительность, особенно при использовании в сочетании с некоторыми алгоритмами более высокого порядка. Поскольку<operator^>является лево-ассоциативным,<x ^infix(f)^ y>на самом деле рассматривается как<(x ^infix(f))^ y>. Однако для гибкости порядок, в котором оба аргумента применяются в инфиксной записи, не имеет значения. Поэтому всегда бывает так, что

(x ^ infix(f)) ^ y == x ^ (infix(f) ^ y)

Тем не менее, обратите внимание, что применение более одного аргумента в фиксированной записи к одной и той же стороне оператора приведет к утверждению времени компиляции:

(infix(f) ^ x) ^ y; // compile-time assertion
y ^ (x ^ infix(f)); // compile-time assertion

Кроме того, функция, созданная с помощью<infix>, может быть частично применена в фиксации. В частности,

(x ^ infix(f))(y1, ..., yn) == f(x, y1, ..., yn)
(infix(f) ^ y)(x1, ..., xn) == f(x1, ..., xn, y)

Rationales

  1. Оператор^был выбран потому, что он левоассоциативный и имеет достаточно низкий приоритет, чтобы большинство выражений отражали ожидаемое поведение.
  2. Оператор не может быть настроен, потому что это потребует большей сложности в реализации; я хочу, чтобы это было как можно проще. Есть также преимущество в том, что унифицированный синтаксис для приложения infix.
Parameters
fФункция, которая получает возможность быть примененной в инфиксации. Функция должна быть, по крайней мере, двоичной; в противном случае будет вызвана ошибка времени компиляции.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
BOOST_HANA_CONSTEXPR_LAMBDA auto divmod = hana::infix([](auto x, auto y) {
// this could be a more efficient implementation
return hana::make_pair(x / y, x % y);
});
int main() {
BOOST_HANA_CONSTEXPR_CHECK((42 ^divmod^ 23) == hana::make_pair(1, 19));
}
template<std::size_t n>
constexpr auto boost::hana::iterate

<#include <boost/hana/functional/iterate.hpp>>

Initial value:
= [](auto&& f) {
return [perfect-capture](auto&& x) -> decltype(auto) {
return f(f( ... f(forwarded(x))));
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Применяет к своему аргументу другую функцию<n>раз.

При наличии функции<f>и аргумента<x><iterate<n>(f, x)>результат применения<f><n>раз к его аргументу возвращается. Другими словами,

iterate<n>(f, x) == f(f( ... f(x)))
^^^^^^^^^^ n times total

Если<n == 0>,<iterate<n>(f, x)>возвращает<x>аргумент без изменений и<f>никогда не применяется. Важно отметить, что функция, переданная<iterate<n>>, должна быть унарной функцией. Действительно, поскольку<f>будет вызвано результатом предыдущего<f>применения, это может занять только один аргумент.

В дополнение к тому, что описано выше,<iterate>также может быть частично применен к аргументу функции из коробки. Другими словами,<iterate<n>(f)>является функциональным объектом, применяющим<f><n>раз к аргументу, с которым он вызван.

iterate<n>(f)(x) == iterate<n>(f, x)

Это предусмотрено для удобства, и оно оказывается особенно полезным в сочетании с алгоритмами более высокого порядка.

Signature

Учитывая функцию \(f : T \to T \) и<x>и аргумент типа данных<T>, подпись \( \mathtt{iterate_n} : (T \to T) \times T \to T \).

Template Parameters
nНеподписанное целое число, представляющее число раз, которое<f>должно быть применено к его аргументу.
Parameters
fДля того, чтобы приложить<n>раз к своему аргументу.
xНачальное значение для вызова<f>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto next_10 = hana::iterate<10>(hana::_ + 1);
static_assert(next_10(3) == 13, "");
constexpr auto xs = hana::make_tuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
static_assert(hana::iterate<3>(hana::make_tuple, xs) ==
hana::make_tuple(hana::make_tuple(hana::make_tuple(xs))), "");
int main() { }
constexpr auto boost::hana::lockstep

<#include <boost/hana/functional/lockstep.hpp>>

Initial value:
= [](auto&& f, auto&& ...g) {
return [perfect-capture](auto&& ...x) -> decltype(auto) {
return forwarded(f)(forwarded(g)(forwarded(x))...);
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Вызов функции в результате вызова других функций на ее аргументы, шаг за шагом.

В частности,<lockstep(f)(g1, ..., gN)>является функцией, которая

lockstep(f)(g1, ..., gN)(x1, ..., xN) == f(g1(x1), ..., gN(xN))

Поскольку каждый<g>вызывается на свой соответствующий аргумент в шаге, число аргументов должно соответствовать числу<g>с.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr int to_int(char c) {
return static_cast<int>(c) - 48;
}
constexpr int increment(int i) {
return i + 1;
}
static_assert(hana::lockstep(hana::plus)(to_int, increment)('3', 4) == 3 + 5, "");
int main() { }
constexpr auto boost::hana::on

<#include <boost/hana/functional/on.hpp>>

Initial value:
= infix([](auto&& f, auto&& g) {
return [perfect-capture](auto&& ...x) -> decltype(auto) {
return forwarded(f)(g(forwarded(x))...);
};
})
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45
constexpr auto infix
Возврат эквивалентной функции, которая также может быть применена в фиксации.
Definition: infix.hpp:79

Вызов функции в результате вызова другой функции на каждый аргумент.

В частности,<on(f, g)>является функцией, которая

on(f, g)(x...) == f(g(x)...)

Для удобства<on>также поддерживает приложение исправления, как предусмотрено<infix>.

Note
on is associative, i.e. on(f, on(g, h)) is equivalent to on(on(f, g), h).

Proof of associativity

on(f, on(g, h))(xs...) == f(on(g, h)(xs)...)
== f(g(h(xs))...)
on(on(f, g), h)(xs...) == on(f, g)(h(xs)...)
== f(g(h(xs))...)

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
// infix application
constexpr auto sorted = hana::sort.by(hana::less ^hana::on^ hana::first, hana::make_tuple(
hana::make_pair(hana::int_c<3>, 'x'),
hana::make_pair(hana::int_c<1>, hana::type_c<void>),
hana::make_pair(hana::int_c<2>, 9876)
));
static_assert(sorted == hana::make_tuple(
hana::make_pair(hana::int_c<1>, hana::type_c<void>),
hana::make_pair(hana::int_c<2>, 9876),
hana::make_pair(hana::int_c<3>, 'x')
), "");
// function call syntax
constexpr auto x = hana::make_pair(1, 2);
constexpr auto y = hana::make_pair(10, 20);
static_assert(hana::on(hana::plus, hana::first)(x, y) == 1 + 10, "");
int main() { }
constexpr auto boost::hana::overload

<#include <boost/hana/functional/overload.hpp>>

Initial value:
= [](auto&& f1, auto&& f2, ..., auto&& fn) {
return [perfect-capture](auto&& ...x) -> decltype(auto) {
return forwarded(fk)(forwarded(x)...);
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Выберите одну из нескольких функций для вызова на основе разрешения перегрузки.

В частности,<overload(f1, f2, ..., fn)>является функциональным объектом, таким, что

overload(f1, f2, ..., fn)(x...) == fk(x...)

где<fk>— функция<f1, ..., fn>, которая была бы названа, если бы разрешение перегрузки выполнялось только среди этого набора функций. Если при разрешении перегрузки будет выбрано более одной функции<fk>, то вызов будет неоднозначным.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <string>
namespace hana = boost::hana;
auto on_string = [](std::string const& s) {
std::cout << "matched std::string: " << s << std::endl;
return s;
};
auto on_int = [](int i) {
std::cout << "matched int: " << i << std::endl;
return i;
};
auto f = hana::overload(on_int, on_string);
int main() {
// prints "matched int: 1"
// prints "matched std::string: abcdef"
BOOST_HANA_RUNTIME_CHECK(f("abcdef") == std::string{"abcdef"});
}
constexpr auto boost::hana::overload_linearly

<#include <boost/hana/functional/overload_linearly.hpp>>

Initial value:
= [](auto&& f1, auto&& f2, ..., auto&& fn) {
return [perfect-capture](auto&& ...x) -> decltype(auto) {
return forwarded(fk)(forwarded(x)...);
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

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

Данная функция<f1, ..., fn>,<overload_linearly(f1, ..., fn)>является новой функцией, которая вызывает первое<fk>, производящее действительное выражение вызова с заданными аргументами. В частности,

overload_linearly(f1, ..., fn)(args...) == fk(args...)

где<fk>являетсяпервойфункцией, такой, что<fk(args...)>является действительным выражением.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
[](int i) { return i + 1; },
[](std::string s) { return s + "d"; },
[](double) { BOOST_HANA_RUNTIME_CHECK(false && "never called"); }
);
int main() {
BOOST_HANA_RUNTIME_CHECK(f("abc") == "abcd");
BOOST_HANA_RUNTIME_CHECK(f(2.2) == static_cast<int>(2.2) + 1);
}
constexpr auto boost::hana::partial

<#include <boost/hana/functional/partial.hpp>>

Initial value:
= [](auto&& f, auto&& ...x) {
return [perfect-capture](auto&& ...y) -> decltype(auto) {
return forwarded(f)(forwarded(x)..., forwarded(y)...);
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Частично применить функцию к некоторым аргументам.

Учитывая функцию<f>и некоторые аргументы,<partial>возвращает новую функцию, соответствующую частично приложенной функции<f>. Это позволяет предоставить некоторые аргументы для функции и позволить остальным аргументам быть предоставленными позже. В частности,<partial(f, x...)>является функцией, которая

partial(f, x...)(y...) == f(x..., y...)
Note
The arity of f must match the total number of arguments passed to it, i.e. sizeof...(x) + sizeof...(y).

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto increment = hana::partial(hana::plus, 1);
static_assert(increment(2) == 3, "");
int main() { }
constexpr unspecified boost::hana::_ {}

<#include <boost/hana/functional/placeholder.hpp>>

Создание простых функций, представляющих операторов C++ inline.

В частности,<_>является объектом, используемым в качестве заполнителя для построения объектов функций, представляющих вызовы операторам C++. Он работает, перегружая операторов между<_>и любым объектом таким образом, что они возвращают объект функции, который фактически вызывает соответствующего оператора на его аргумент (ы). Следовательно, для любого поддерживаемого оператора<@>:

(_ @ _)(x, y) == x @ y

Операторы также могут быть частично применены к одному аргументу:

(x @ _)(y) == x @ y
(_ @ y)(x) == x @ y

При вызове большего количества аргументов, чем требуется, функции, созданные с помощью<_>, отбрасывают лишнее вместо того, чтобы вызвать ошибку:

(_ @ _)(x, y, z...) == x @ y

Это делает функции, созданные с помощью<_>, более простыми в использовании в алгоритмах более высокого порядка, которые иногда предоставляют больше информации, чем необходимо для их обратного вызова.

Supported operators

  • Арифметика: бинарная+, двоичный-,/,*,%, унарный+, унитарный-
  • ~,&,|,^,<<,>>
  • ==,!=,<,<=,>,>=
  • Логика:||,&&,!
  • Доступ к члену:*(отнесение),[](массовый подстрочный текст)
  • Другое:()(функциональный звонок)

Более сложные функции, такие как возможность компоновать заполнители в более крупные объекты функций, не поддерживаются. Это нарочно; вы должны либо использовать общие лямбды C++14, либо библиотеку, такую какBoost.Phoenix, если вам нужно больше оружия. Цель состоит в том, чтобы спасти пару персонажей в простых ситуациях.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto plus = hana::_ + hana::_;
static_assert(plus(1, 2) == 1 + 2, "");
constexpr auto increment = hana::_ + 1;
static_assert(increment(1) == 2, "");
constexpr auto twice = 2 * hana::_;
static_assert(twice(1) == 2, "");
// Extra arguments are ignored.
static_assert(twice(1, "ignored") == 2, "");
int main() { }
constexpr auto boost::hana::reverse_partial

<#include <boost/hana/functional/reverse_partial.hpp>>

Initial value:
= [](auto&& f, auto&& ...x) {
return [perfect-capture](auto&& ...y) -> decltype(auto) {
return forwarded(f)(forwarded(y)..., forwarded(x)...);
};
}
constexpr auto capture
Создать функцию захвата заданных переменных.
Definition: capture.hpp:45

Частично применить функцию к некоторым аргументам.

При наличии функции<f>и некоторых аргументов<reverse_partial>возвращает новую функцию, соответствующую<f>, последние аргументы которой частично применяются. В частности,<reverse_partial(f, x...)>является функцией, которая

reverse_partial(f, x...)(y...) == f(y..., x...)
Note
The arity of f must match the total number of arguments passed to it, i.e. sizeof...(x) + sizeof...(y).

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto half = hana::reverse_partial(hana::div, 2);
static_assert(half(4) == 2, "");
static_assert(half(8) == 4, "");
int main() { }

Статья Boost.Hana: Functional раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 09:51:53/0.01672101020813/1